2014-08-31 9 views
6

Я хочу написать функцию Haskell, которая возвращает список, добавленный к нему, счетчик времени (например, lst * count в Python).версия Pointfree не скомпилирована, но точечная делает?

Моя первая попытка:

self_append_n :: Int -> [a] -> [a] 
self_append_n = concat . replicate 

Мои рассуждения в том, что replicate принимает количество и значение, и выдает список значений. Когда значение само по себе является списком, остается только объединить списки вместе. Тем не менее, это дает изумительное ошибку:

Couldn't match type `[a0]' with `[a] -> [a]' 
Expected type: [[a0]] -> [a] -> [a] 
    Actual type: [[a0]] -> [a0] 
In the first argument of `(.)', namely `concat' 
In the expression: concat . replicate 
In an equation for `self_append_n': 
    self_append_n = concat . replicate 

Тогда я написал уместный вариант:

self_append_n a b = concat $ replicate a b 

и это работает!

Почему точка без возможности компиляции, но добавление точек заставляет ее работать?

ответ

11

Это, вероятно, помогает явно parenthesise подписи:

selfAppend :: Int -> ([a]   -> [a]) 
replicate :: Int -> ([a]->[[a]]) 
concat  ::   [[a]]  -> [a] 

Если попытаться составить concat . replicate, вы в конечном итоге дает concat частично appied результат из replicate, т.е. [a] -> [[a]]. Это не объединяется с [[a]].

Прежде чем передать результат, необходимо сначала передать как аргументам replicate. ИМО лучший способ сделать это "пол-pointfree":

selfAppend n = concat . replicate n 

менее читаемой альтернативой будет

selfAppend' = curry $ concat . uncurry replicate 
selfAppend'' = (concat.) . replicate 

Или с печально известным оператором

(.:) :: (c->d) -> (a->b->c) -> a->b->d 
(.:) = (.).(.) 
-- `≡ fmap fmap fmap`, also a popular implementation... 

вы можете просто написать

selfAppend''' = concat .: replicate 
+4

Получаю. Композиция терпит неудачу, потому что фактический тип репликации не является списком, а функцией (которая сама возвращает список). –

+1

Да. К сожалению, всякая философия Хаскелла не всегда является преимуществом (хотя и очень часто). – leftaroundabout