#haskell #type-mismatch
#haskell #несоответствие типов
Вопрос:
Я не могу понять, почему функция:
repli :: [a] -> Int -> [a]
repli xs n = concatMap (replicate n) xs
невозможно переписать как:
repli :: [a] -> Int -> [a]
repli [] _ = []
repli (x:xs) n = (take n $ repeat x) : repli xs n
или
repli :: [a] -> Int -> [a]
repli [] _ = []
repli (x:xs) n = (replicate n x) : repli xs n
Ghci жалуется:
Couldn't match expected type ‘a’ with actual type ‘[a]’
‘a’ is a rigid type variable bound by
the type signature for repli :: [a] -> Int -> [a]
at 99questions.hs:41:10
Relevant bindings include
xs :: [a] (bound at 99questions.hs:43:10)
x :: a (bound at 99questions.hs:43:8)
repli :: [a] -> Int -> [a] (bound at 99questions.hs:42:1)
In the first argument of ‘(:)’, namely ‘(replicate n x)’
In the expression: (replicate n x) : repli xs n
Я не понимаю, почему, поскольку при выполнении всех вычислений типа получается нормально. repeat x
есть [a]
и так take n
есть [a]
. Поэтому он не должен жаловаться.
Комментарии:
1. Я не совсем понимаю ваши намерения — почему вы передаете список в качестве аргумента? Похоже, вы пытаетесь воссоздать
replicate
то, что работает с отдельными элементами.2. @shree.pat18: Да, это упражнение. Я просматриваю список 99 проблем Haskell.
Ответ №1:
Подпись (:)
есть a -> [a] -> [a]
. Поэтому у вас не может быть списков с обеих сторон оператора. Это причина вашей ошибки.
Вместо этого вы могли бы использовать ( )
, который имеет подпись [a] -> [a] -> [a]
.
Комментарии:
1. И в первой функции (рабочей) была даже concat Map!