2015-01-26 7 views
0

Я пытаюсь цепь вместе функций через аппликативном шаблон функтора, но у меня возникает проблемы компиляция моего кода:Haskell аппликативен функтор - сборник отказ

import Control.Applicative 

buildMyList :: Float -> Float -> [Float] 
buildMyList ul tick = [p | p <- [0,tick..ul]] 

myFunctionChain :: [Float] 
myFunctionChain = reverse <$> buildMyList 100 1 

Когда я пытаюсь скомпилировать это я получаю следующая ошибка компиляции:

Couldn't match type 'Float' with '[a0]' 
Expected type: [[a0]] 
    Actual type: [Float] 
In the return type of call of 'buildMyList' 

Мне кажется, что мне не удалось сопоставить ожидаемый контекст возврата с фактическим контекстом. Не имея достаточного опыта в этой области, я не могу получить больше!

+2

Вам не нужно 'Applicative' здесь. Обычное приложение-функция будет делать: 'reverse (buildMyList 100 1)' или 'reverse $ buildMyList 100 1'. – phadej

+0

да, я согласен с вами. Это должно быть примером для игрушек, поскольку я пытаюсь понять, почему он не работает, поэтому я могу построить свои знания –

ответ

1

Applicative можно было бы лучше объяснить с помощью bulldMyList. Предположим, вы хотите построить массив квадратной матрицы: [(0,0), (0,1), (0,2), (1, 0) ...]. Использование списочные:

buildMyMatrix :: Int -> Int -> [(Int, Int)] 
buildMyMatrix maxX maxY = [(x, y) | x <- [0..maxX], y <- [0..maxY]] 

Использования аппликативных комбинаторов его можно переписать в виде:

buildMyMatrix maxX maxY = pure (\x y -> (x, y)) <*> [0..maxX] <*> [0..maxY] 

И согласно аппликативным законам мы можем переписать pure f <*> x = f <$> x, для всех f и x:

buildMyMatrix maxX maxY = (\x y -> (x, y)) <$> [0..maxX] <*> [0..maxY] 

Мне пришлось использовать немного больше icated buildMyMatrix, так как ваш buildMyList слишком тривиальным воспользоваться Applicative:

buildMyList :: Float -> Float -> [Float] 
buildMyList ul tick = [p | p <- [0,tick..ul]] 
buildMyList ul tick = id <$> [0,tick..ul] -- [by functor identity law]: 
buildMyList ul tick = [0,tick..ul] 
+0

. Наверное, я просто пытался понять, как я могу объединить функции, которые являются функторами, элегантным способом. Я полагаю, что я мог бы использовать примечание –

+0

Если вы хотите связать функции формы 'Applicative f => a -> fb' или' Monad m => a -> mb', существует много разных способов, в зависимости от того, как вы как их цеплять. [Недавний вопрос] (http://stackoverflow.com/questions/28150825/how-can-i-use-with-a-maybe-a) уже есть два ответа, которые, вероятно, интересны для работы (например, какие экземпляры применяются). Я нахожу оба неясными, но они показывают силу абстракции. – phadej

Смежные вопросы