Проблема синтаксическая, в этой строке:
foreach x:[] f = (f x):[]
Приложение-конструктор в шаблонах обычно необходимо заключить в скобки. Это будет работать:
foreach (x:[]) f = (f x):[]
Между прочим ... применение функции имеет наивысший приоритет, поэтому с другой стороны вам не нужны скобки справа:
foreach (x:[]) f = f x:[]
Вышеприведенное справедливо для любого инфиксного конструктора, но, как последнее замечание, для списков, в частности, существует специальный синтаксис:
foreach [x] f = [f x]
Есть другие проблемы с вашим кодом в его нынешнем виде, но это немедленная ошибка. Краткий обзор других проблем:
foreach :: [a] → f → [r]
Переменные типа неявно определяются количественно, поэтому это означает любой тип f
. Вам нужен более конкретный тип, а именно a -> r
.
foreach x:[] f = (f x):[]
В этом нет необходимости - рекурсивный регистр здесь будет работать правильно, применяя f
к x
и вызывая себя в хвост, давая пустой список списка.
foreach []:x f = []:(f x)
Я не думаю, что это означает, что вы думаете, что это означает - это шаблон, сопоставляющий заголовок списка пустому списку []
, подразумевая, что функция работает со списком списков.
foreach (x:xs) f = (f x) : (foreach (xs f))
Скобки здесь либо не нужны, либо неверны. Опять же, приложение функции имеет более высокий приоритет, чем операторы типа :
. Кроме того, (xs f)
означает применение xs
к f
, как если бы это была функция. Чтобы применить foreach
к двум аргументам, достаточно просто foreach xs f
.
Для сравнения вот исходный код стандартной библиотечной функции (идентичной, за исключением порядка аргументов) map
:
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs