我正在尝试使用.运算符编写一个函数,它接受三个值并返回它们的最大值.
显然,以下工作
max3 a b c = max a (max b c)
max3 a b c = max a $ max b c
Run Code Online (Sandbox Code Playgroud)
但我想用..我试过了
max3 a b c = max a . max b c
Run Code Online (Sandbox Code Playgroud)
但得到错误
Couldn't match expected type `a0 -> Float' with actual type `Float'
In the first argument of `max', namely `b'
Run Code Online (Sandbox Code Playgroud)
我知道这个例子很愚蠢,但对正确的方法做了很好的解释,为什么会非常感激.
回想一下定义(.):
(f . g) x = f (g x)
Run Code Online (Sandbox Code Playgroud)
你有表达
max a (max b c)
Run Code Online (Sandbox Code Playgroud)
它的右侧匹配(f . g) x,如果我们设置f = max a,g = max b和x = c.在定义的左侧使用这些替换(.),我们得到:
(max a . max b) c = max a (max b c)
Run Code Online (Sandbox Code Playgroud)
让我们在第一个例子中介绍一些括号:
max3 a b c = (max a) ((max b) c)
Run Code Online (Sandbox Code Playgroud)
现在将它与你上一个的那个进行比较:
max3 a b c = (max a) . ((max b) c)
Run Code Online (Sandbox Code Playgroud)
或者,如果我们用(.)前缀表示法写:
max3 a b c = (.) (max a) ((max b) c)
Run Code Online (Sandbox Code Playgroud)
现在我们明白为什么你会得到这个错误.为了进行类型检查,(max b) c需要是一个函数:
(.) :: (b -> c ) -> (a -> b ) -> a -> c
max a :: Float -> Float
max b c :: Float
^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
如果我们使用约束版本,我们会收到更好的错误消息max:
maxFloat :: Float -> Float -> Float
maxFloat = max
max3 a b c = max a . max b c
Run Code Online (Sandbox Code Playgroud)
现在错误消息好多了:
Run Code Online (Sandbox Code Playgroud)Couldn't match expected type ‘a0 -> Float’ with actual type ‘Float’ Possible cause: ‘maxFloat’ is applied to too many arguments In the second argument of ‘(.)’, namely ‘maxFloat b c’ In the expression: maxFloat a . maxFloat b c
话虽这么说,让我们实际解决这个问题:
max3 a b c = max a ((max b) c)
= (max a . max b) c
Run Code Online (Sandbox Code Playgroud)
请注意,您也可以写
max3 :: Ord a => a -> a -> a -> a
max3 a b = max a . max b
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
76 次 |
| 最近记录: |