Haskell 两个二元函数的函数组合?
Haskell Function composition of two binary functions?
我正在努力完成 20 Intermediate Haskell exercises,但在练习 13 上卡住了:
-- Exercise 13
-- Relative Difficulty: 6
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = error "todo"
其中 Misty Typeclass 本质上是 Monad Typeclass 并且是这样实现的:
class Misty m where
banana :: (a -> m b) -> m a -> m b
unicorn :: a -> m a
出于好奇,我在网上找到了这个练习的解决方案
apple = banana . flip furry'
其中 furry' 是实现为
的 liftM 版本
furry' f mi = banana (\x -> unicorn (f x)) mi
我不明白的是函数组合 (.) 在两个二元函数(即 banana 和 flipped furry')上的使用,如果有人可以完成这个评估,我认为这会对我有所帮助很多。
让我们一步步开始吧。 Misty
类型类已给出:
class Misty m where
banana :: (a -> m b) -> m a -> m b
unicorn :: a -> m a
此外 furry'
已经在这些练习中的较早问题中得到解决:
furry' :: Misty m => (a -> b) -> m a -> m b
furry' f mi = banana (\x -> unicorn (f x)) mi
现在您有 apple
函数,您必须定义它:
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = error "todo"
现在尝试遵循类型签名。假设您这样定义 apple
:
apple xs ys
xs will have type of m a
ys will have type of m (a -> b)
现在你能看出上述类型与furry'
之间的关系了吗?所以
你必须以某种方式将 xs
和 ys
应用到 furry'
现在因为它是
第二个参数是m a
,你已经在xs
中有了,你可以使用
flip
获取方式:
flip furry' :: m a -> (a -> b) -> m b
所以你可以将 xs
应用到它的第一个参数,你将拥有
以下类型签名:
(flip furry') xs :: (a -> b) -> m b
-------- 方程 1
猜猜如何应用它 ys
?尽量统一上面的类型
第一个参数为 banana
的签名:
那会给你:
a ~ (a -> b)
m b ~ (m b)
因此,banana
的类型签名从
转换而来
banana :: (a -> m b) -> m a -> m b
至
banana :: ((a -> b) -> m b) -> m (a -> b) -> m b
现在从 Equation (1)
我们知道 (flip furry') xs
类型签名匹配
banana
和 ys
的第一个参数匹配第二个参数
banana
。这给了你 apple
:
的定义
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple xs ys = banana ((flip furry') xs ) ys
可以用pointfree的方式表示为:
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = banana . flip furry'
我正在努力完成 20 Intermediate Haskell exercises,但在练习 13 上卡住了:
-- Exercise 13
-- Relative Difficulty: 6
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = error "todo"
其中 Misty Typeclass 本质上是 Monad Typeclass 并且是这样实现的:
class Misty m where
banana :: (a -> m b) -> m a -> m b
unicorn :: a -> m a
出于好奇,我在网上找到了这个练习的解决方案
apple = banana . flip furry'
其中 furry' 是实现为
的 liftM 版本furry' f mi = banana (\x -> unicorn (f x)) mi
我不明白的是函数组合 (.) 在两个二元函数(即 banana 和 flipped furry')上的使用,如果有人可以完成这个评估,我认为这会对我有所帮助很多。
让我们一步步开始吧。 Misty
类型类已给出:
class Misty m where
banana :: (a -> m b) -> m a -> m b
unicorn :: a -> m a
此外 furry'
已经在这些练习中的较早问题中得到解决:
furry' :: Misty m => (a -> b) -> m a -> m b
furry' f mi = banana (\x -> unicorn (f x)) mi
现在您有 apple
函数,您必须定义它:
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = error "todo"
现在尝试遵循类型签名。假设您这样定义 apple
:
apple xs ys
xs will have type of m a
ys will have type of m (a -> b)
现在你能看出上述类型与furry'
之间的关系了吗?所以
你必须以某种方式将 xs
和 ys
应用到 furry'
现在因为它是
第二个参数是m a
,你已经在xs
中有了,你可以使用
flip
获取方式:
flip furry' :: m a -> (a -> b) -> m b
所以你可以将 xs
应用到它的第一个参数,你将拥有
以下类型签名:
(flip furry') xs :: (a -> b) -> m b
-------- 方程 1
猜猜如何应用它 ys
?尽量统一上面的类型
第一个参数为 banana
的签名:
那会给你:
a ~ (a -> b)
m b ~ (m b)
因此,banana
的类型签名从
banana :: (a -> m b) -> m a -> m b
至
banana :: ((a -> b) -> m b) -> m (a -> b) -> m b
现在从 Equation (1)
我们知道 (flip furry') xs
类型签名匹配
banana
和 ys
的第一个参数匹配第二个参数
banana
。这给了你 apple
:
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple xs ys = banana ((flip furry') xs ) ys
可以用pointfree的方式表示为:
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = banana . flip furry'