我可以在Haskell中创建自己的函数组合运算符吗?
Haskell中的函数组合运算符定义为:我可以在Haskell中创建自己的函数组合运算符吗?,haskell,functional-programming,Haskell,Functional Programming,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
(.) :: (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.
您的函数
o
非常类似于函数组合
:
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
o = (flip .) . flip . (flip .) $ (.)
您可以重写
的定义,只需稍微重新排列参数:
o :: a -> (a -> b) -> (b -> c) -> c
o x f g = g (f x)
或者,您可以尝试创建o
,方法是在
的参数周围来回移动:
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
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 .)
如果您想知道为什么(翻转)
交换第二个和第三个参数,我建议您阅读和。它归结为
确保翻转
应用于传递给(翻转)
的任何函数的结果,并且交换函数结果的第一个和第二个参数与交换其第二个和第三个参数相同
不过,老实说,我认为没有必要使用
o
函数,因为您可以将f
重写为:
f :: Int -> String
f x = g . h $ x
甚至
f = g . h
您的函数
o
非常类似于函数组合
:
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
o = (flip .) . flip . (flip .) $ (.)
您可以重写
的定义,只需稍微重新排列参数:
o :: a -> (a -> b) -> (b -> c) -> c
o x f g = g (f x)
或者,您可以尝试创建o
,方法是在
的参数周围来回移动:
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
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 .)
如果您想知道为什么(翻转)
交换第二个和第三个参数,我建议您阅读和。它归结为
确保翻转
应用于传递给(翻转)
的任何函数的结果,并且交换函数结果的第一个和第二个参数与交换其第二个和第三个参数相同
不过,老实说,我认为没有必要使用
o
函数,因为您可以将f
重写为:
f :: Int -> String
f x = g . h $ x
甚至
f = g . h
它不起作用的原因正是错误消息所说的:您为
o
编写了类型签名,但没有编写定义,例如o x f g=g(f x)
。它不起作用的确切原因是错误消息说:您为o
编写了类型签名,但没有编写定义,例如o x f g=g(f x)
。