Haskell中的函数组合运算符定义为:
(.) :: (b -> c) -> (a -> b) -> a -> c
当我尝试在Haskell中创建自己的函数组合运算符o
时,它不起作用,我做错了什么?
o :: a -> (a -> b) -> (b -> c) -> c
g :: Double -> String
g x = show x
h :: Int -> Double
h x = fromIntegral x
f :: Int -> String
f x = o x h g -- can it also be written like this: f = o h g
错误讯息:
C:\Users\August\Desktop\Haskell\Template\Ex.hs:36:1: error:
The type signature for `o' lacks an accompanying binding
Failed, modules loaded: none.
答案 0 :(得分:2)
您的函数o
与函数组合.
非常相似:
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
您可以重写.
的定义,并稍微重新排列参数:
o :: a -> (a -> b) -> (b -> c) -> c
o x f g = g (f x)
或者你可以尝试通过改变o
的参数来创建.
:
o = (flip .) . flip . (flip .) $ (.)
在这个定义中,我们使用flip
来交换(.)
和(flip .)
的第一个和第二个参数来交换第二个和第三个参数。对于能够给我们的函数a -> b -> c -> d
:
a -> b -> c -> d
-- swap b and c with (flip .)
a -> c -> b -> ->d
-- swap a and c with (.)
c -> a -> b -> -> d
-- swap a and b
c -> b -> a -> d with (flip .)
如果您想知道为什么(flip .)
交换了第二个和第三个参数,建议您阅读this answer和the blog post that was linked in it。它归结为.
,确保flip
应用于传递给(flip .)
的任何函数的结果,并交换函数结果的第一个和第二个参数是相同的交换第二和第三个论点。
说实话,我并不认为您需要o
功能,因为您可以将f
重写为:
f :: Int -> String
f x = g . h $ x
甚至
f = g . h