Во-первых, формат кода:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun t = (\b -> if b == (pred (fst t))
then Nothing
else Just (b, pred b)) (snd t)
Далее, дважды проверьте тип unfoldr
с помощью Hoogle:
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
Далее добавьте тип подписи fun
так, что GHC скажет вам, что проблема в. По типу unfoldr
, fun
должен иметь тип:
b ~ Char
a ~ Char
fun :: Char -> Maybe (Char, Char)
, поскольку вы unfoldr
в исходном примере с snd t
.
Я обычно проверить небольшие кусочки, так что мы можем удалить определение из foo
и просто использовать сигнатуру типа:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun t
fun:: Char -> Maybe (Char, Char)
fun b = error ""
GHC жалуется, что t
имеет тип (Char, Char)
но fun
ожидает типа Char
. Вы вызывали unfoldr fun t
вместо unfoldr fun (snd t)
, как в исходном примере. Переместить этот бит из fun
в revRange
:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr fun (snd t)
fun:: Char -> Maybe (Char, Char)
fun b = error ""
Далее добавьте в определении fun
снова. Мы можем удалить лямбда и поставить b
как обычный аргумент fun
:
fun:: Char -> Maybe (Char, Char)
fun t b = if b == (pred (fst t))
then Nothing
else Just (b, pred b)
Сразу мы видим еще вопиющие проблемы: fun
занимает два аргументов, но подпись говорит, что это займет всего один!
t
Поскольку константа в оригинальном лямбда, мы можем решить эту проблему путем частичного применения fun
в revRange
, поэтому окончательный ответ:
revRange :: (Char,Char) -> [Char]
revRange t = unfoldr (fun t) (snd t)
fun:: (Char, Char) -> Char -> Maybe (Char, Char)
fun t b = if b == (pred (fst t))
then Nothing
else Just (b, pred b)
Для решения комментарий, вы бы как писать
revRange :: (Char,Char) -> [Char]
revRange = unfoldr fun2
Используя тот же подход, что и выше, в подписи unfoldr
мы должны b ~ (Char,Char)
и a ~ Char
.Таким образом, мы хотели бы fun2
иметь тип
fun2 :: ((Char,Char) -> Maybe (Char, (Char, Char)))
Я оставлю определение fun2
в качестве упражнения. В качестве подсказки я предлагаю принять соглашение о том, что первая часть пары является постоянной и содержит fst t
.
Похоже, что вы включили 'snd t', который является вторым аргументом' unfoldr' в исходной версии, в 'fun', который должен быть только лямбда-выражением? – kosmikus