2014-11-11 2 views
2

Если у вас есть список типов IO [Double], я хочу, чтобы проверить, что список имеет желаемую длину.Haskell: проверьте длину IO [Double]

Я предполагаю, что мне нужно использовать функторы здесь, но я не понимаю, как это определить. Я пишу экземпляр-функтор функции длины? Или я пишу экземпляр-функтор типа данных, который использует функцию длины в fmap?

Монады, функторы и т. Д. - все это для меня очень ново.

+2

Пишешь экземпляр functor для «действия», в котором вы работаете: 'IO'. За исключением, конечно, вам фактически не нужно делать это самостоятельно, экземпляр уже определен в прелюдии; все, что вам осталось сделать, это _invoke_ этот экземпляр, используя 'fmap' один раз. – leftaroundabout

+0

Спасибо за разъяснение! – asdfasdf1234

ответ

10

Значение типа IO [Double] не имеет длины, поскольку оно не является списком парных разрядов, а скорее действием ввода-вывода, которое при выполнении производит список парных разрядов. Таким образом, невозможно написать функцию типа IO [a] -> Int.

С помощью этой функции вы можете легко написать сообщение о функции типа IO [a] -> IO Int, что так же просто, как fmap length.

3

Скорее всего, вам нужно получить список, а затем вычислить его длину. Как правило, вы захотите сделать это с помощью обозначения (хотя это не обязательно).

Haskell инкапсулирует все IO в IO-монаду, поэтому вы можете получить только список из IO [Double] в другом объекте типа IO a. Код будет выглядеть примерно так this-

main::IO() 
main = do 
    theList <- getList --or whatever your object of type IO [Double] is 
    let theLength = length theList 
    .... -- Do stuff with theLength here 
+0

@ jcast- Вы абсолютно правы ... Я изменил формулировку. – jamshidh

+0

Это более естественно сделать так, если вам нужен список и для чего-то другого, кроме его длины. Но подход «fmap» может быть лучше при других обстоятельствах. – dfeuer

+0

@ dfeuer - подход «fmap» - это, как правило, то, что я буду делать, но это то, что я покажу начинающему. – jamshidh

1

Оба ответов вывешенных до сих пор является правильным и хорошим путем решения этой проблемы, но я хотел бы указать третий синтаксис для выполнения того же эффекта. Это эффективно jamshidh's answer минус синтаксический сахар do -notation:

ioLength :: IO [Double] -> IO Int 
ioLength a = a >>= (\x -> return $ length x) 

Или, более сжато:

ioLength a = a >>= (return . length) 

Что, если конденсируется даже дальше, дает amalloy's answer:

ioLength = fmap (length)