初学者/学习者在haskell中实现foreach

Ste*_*and 6 haskell pattern-matching

我试图实现一个foreach态射,以测试我对态射定义和模式匹配的理解......显然我完全错过了这两点.

你能纠正我吗?我想射foreach来采取的列表a和一个态射f作为参数,并返回所有结果列表中rf适用于所有a的元素.

foreach :: [a] ? f ? [r]
foreach [] f = []
foreach x:[] f = (f x):[]
foreach []:x f = []:(f x)
foreach (x:xs) f = (f x) : (foreach (xs f))
Run Code Online (Sandbox Code Playgroud)

编译时,我有 src\Main.hs:23:0: Parse error in pattern

C. *_*ann 13

问题是语法,在这一行:

foreach x:[] f = (f x):[]
Run Code Online (Sandbox Code Playgroud)

模式中的构造函数应用程序通常需要括起来.这可行:

foreach (x:[]) f = (f x):[]
Run Code Online (Sandbox Code Playgroud)

顺便提一下......函数应用程序是最高优先级,所以另一方面你不需要在右边的括号:

foreach (x:[]) f = f x:[]
Run Code Online (Sandbox Code Playgroud)

上面适用于任何中缀构造函数,但作为最后一点,特别是列表有一个特殊的语法:

foreach [x] f = [f x]
Run Code Online (Sandbox Code Playgroud)

您的代码存在其他问题,但这是即时错误.快速概述其他问题:

foreach :: [a] ? f ? [r]
Run Code Online (Sandbox Code Playgroud)

类型变量是隐式普遍量化的,因此这意味着任何类型f.你需要一个更具体的类型,即a -> r.

foreach x:[] f = (f x):[]
Run Code Online (Sandbox Code Playgroud)

这是不必要的-递归情况下将正常工作在这里,将fx和一个自称尾部,给人的空单的情况.

foreach []:x f = []:(f x)
Run Code Online (Sandbox Code Playgroud)

我不认为这意味着你认为它意味着什么 - 这是模式匹配列表的头部与空列表[],暗示该功能正在列表列表上工作.

foreach (x:xs) f = (f x) : (foreach (xs f))
Run Code Online (Sandbox Code Playgroud)

这里的括号要么不必要要么不正确.同样,函数应用程序的优先级高于运算符:.此外,(xs f)意味着应用xsf,就好像它是一个函数.要申请foreach两个论点,foreach xs f就足够了.


为了比较,这里是(参数顺序除外)标准库函数的源代码map:

map :: (a -> b) -> [a] -> [b]
map _ []     = []
map f (x:xs) = f x : map f xs
Run Code Online (Sandbox Code Playgroud)