Ste*_*and 6 haskell pattern-matching
我试图实现一个foreach态射,以测试我对态射定义和模式匹配的理解......显然我完全错过了这两点.
你能纠正我吗?我想射foreach
来采取的列表a
和一个态射f
作为参数,并返回所有结果列表中r
的f
适用于所有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)
这是不必要的-递归情况下将正常工作在这里,将f
要x
和一个自称尾部,给人的空单的情况.
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)
意味着应用xs
到f
,就好像它是一个函数.要申请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)