我正在大学的课程中学习Haskell,并且有一个考试练习,我们需要定义一个函数,它接受一个函数列表 [(Int ->Int)]和一个Type的另一个参数Int并返回一个Int.所以类型应该是
compose :: [(Int ->Int)] -> Int -> Int.
Run Code Online (Sandbox Code Playgroud)
该函数应从左到右返回列表中函数的组合,并将其应用于第二个参数.我尝试了以下方法:
compose :: [(Int -> Int)] -> Int -> Int
compose [] x = x
compose (f:fs) x
|fs == [] = f x
|f : (compose fs x)
Run Code Online (Sandbox Code Playgroud)
但编译器抛出一个错误:
003Exam.hs:24:22:
Couldn't match expected type ‘Int’ with actual type ‘[Int -> Int]’
In the expression: f : (compose fs x)
In an equation for ‘compose’:
compose (f : fs) x
| fs == [] = f x
| otherwise = f : (compose fs x)
003Exam.hs:24:28:
Couldn't match expected type ‘[Int -> Int]’ with actual type ‘Int’
In the second argument of ‘(:)’, namely ‘(compose fs x)’
In the expression: f : (compose fs x)
Run Code Online (Sandbox Code Playgroud)
如果我离开最后一行,例如:
compose :: [(Int -> Int)] -> Int -> Int
compose [] x = x
compose (f:fs) x
|fs == [] = f x
Run Code Online (Sandbox Code Playgroud)
然后我也得到一个错误 - 这是我真正不理解的错误:
003Exam.hs:23:13:
No instance for (Eq (Int -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from a use of ‘==’
In the expression: fs == []
In a stmt of a pattern guard for
an equation for ‘compose’:
fs == []
In an equation for ‘compose’: compose (f : fs) x | fs == [] = f x
Run Code Online (Sandbox Code Playgroud)
如果有任何帮助澄清我做错了什么,我会很高兴.
首先,(:)仅用于在列表的前面添加元素(或模式匹配那些元素),因此您必须替换
f : compose fs x
Run Code Online (Sandbox Code Playgroud)
同
f (compose fs x)
Run Code Online (Sandbox Code Playgroud)
接下来,您必须Bool在防护中使用类型或模式匹配的表达式:
| fs == [] = -- this line is still wrong, see below
| otherwise = f (compose f xs)
Run Code Online (Sandbox Code Playgroud)
但是,没有Eq功能实例.两个函数的等价性是不可判定的(通常),因此使用null :: [a] -> Bool而不是(==) :: Eq a => [a] -> [a] -> Bool:
compose :: [(Int -> Int)] -> Int -> Int
compose [] x = x
compose (f:fs) x
| null fs = f x
| otherwise = f (compose fs x)
Run Code Online (Sandbox Code Playgroud)
既然compose [] x与x你甚至可以删除支票相同:
compose :: [(Int -> Int)] -> Int -> Int
compose [] x = x
compose (f:fs) x = f (compose fs x)
Run Code Online (Sandbox Code Playgroud)
compose [(+1), (+2)] 1(用它的定义替换它)而不去掉中间术语.你注意到一个模式吗?compose.