Объединение элементов в список в анонимной функции в Haskell

Я новичок в Haskell и не могу найти причину, по которой я не могу это скомпилировать:

test = foldr (\x y -> y : x) [1]

Я не пытаюсь добиться чего-либо функционально для фиктивной функции «тест».

Просто я продолжаю получать этот код ошибки:

Occurs check: cannot construct the infinite type: a0 = [a0]
    In the first argument of `(:)', namely `y'
    In the expression: y : x
    In the first argument of `foldr', namely `(\ x y -> y : x)'

Все, что я хочу сделать, это иметь возможность объединять элементы из списка, чтобы сформировать другой список в анонимной функции, определенной в другой функции (в данном случае, определенной в «тесте».)

Спасибо.


person ali    schedule 14.10.2012    source источник
comment
Вы пробовали foldr (\x y -> x : y) [1] (или, что то же самое, только foldr (:) [1])?   -  person huon    schedule 14.10.2012
comment
на самом деле я пытался упростить более серьезную проблему, связанную с типами.   -  person ali    schedule 14.10.2012
comment
Что ж, причина, вероятно, будет аналогичной, только более сложной. Если вы покажете нам более серьезную проблему, возможно, мы сможем помочь и с ней.   -  person Daniel Fischer    schedule 14.10.2012
comment
@DanielFischer хорошо, я опубликую это в другом вопросе. Спасибо.   -  person ali    schedule 14.10.2012
comment
Это ссылка на более серьезную проблему stackoverflow.com/questions/12883559/   -  person ali    schedule 14.10.2012


Ответы (1)


Тип foldr:

foldr :: (a -> b -> b) -> b -> [a] -> b

поэтому, если мы попытаемся использовать его

test = foldr (\x y -> y : x) [1]

мы должны иметь следующие типы:

b = Num n => [n]

поскольку аргумент для пустого списка ввода имеет этот тип, и

(\x y -> y : x) :: (a -> b -> b)
                :: Num n => (a -> [n] -> [n])

Но лямбда равна flip (:) и поэтому имеет тип

(\x y -> y : x) :: [t] -> t -> [t]

и пытаясь объединить это с a -> [n] -> [n], мы находим

a == [t]
t == [n]
[t] == [n]

что подразумевает t == [t].

Если вы не flip минусы (:), он будет проверять тип, но функцию будет проще выразить как

test xs = xs ++ [1]

или без точек

test = (++ [1])
person Daniel Fischer    schedule 14.10.2012
comment
не могли бы вы рассказать подробнее, поскольку аргумент для пустого списка ввода имеет такой тип. Когда вы говорите спор, что вы имеете в виду? - person ali; 14.10.2012
comment
Второй аргумент foldr — это результат для пустого входного списка, он имеет тип b; в вашем примере этот аргумент равен [1] и [1] :: Num n => [n]. Дайте подумать, как лучше это выразить. - person Daniel Fischer; 14.10.2012