haskell - 使用 Applicative 和 Functor 的 Haskell 函数
问题描述
我有一个练习题,给了我一个函数:
sequence :: Applicative f => [f a] -> f[a]
sequence = foldr (_hole (:)) (pure [])
问题是:
"What type is required for the function that needs to be placed at
_hole in the following expression? Also give a definition for the
expression using and <$> and <*>".
我在理解问题所在时遇到问题。因此,对于我所尝试的,我假设我需要指定运算符,因为它使用的是 foldr,所以我假设它类似于 sequence = foldr((+) (:)) (pure[])。
然后对于表达式的定义,我写了如下内容:
sequence :: <*> f => [f a] -> f[a]
sequence = foldr <$> pure []
我很确定我不是 100% 正确的,所以如果有任何更正,我将不胜感激。
解决方案
该练习希望您假设在_hole
某处定义了某个值,并且上面的代码进行了类型检查。然后,目标是确定 that 的类型是什么_hole
。然后,它会询问 的可能定义_hole
。
例如,如果给我们
foo :: Int
foo = 3 + _hole
答案应该是_hole :: Int
,因为这是我们使上面的代码工作所需要的。因为定义_hole = 2
没问题。
相反,在
foo :: Int -> Bool
foo = const _hole "hello" True
然后我们需要_hole :: Bool -> Int -> Bool
和例如_hole = \b i -> b
。
你自己的代码比较复杂,所以最好把所有的步骤都写下来:
sequence :: Applicative f => [f a] -> f[a]
sequence = foldr (_hole (:)) (pure [])
这里foldr
使用,它(在列表上)有类型
foldr :: (b -> c -> c) -> c -> [b] -> c
要进行类型检查,参数必须具有类型
_hole (:) :: b -> c -> c
pure [] :: c
, 仅用两个参数调用的结果foldr
是
sequence :: [b] -> c
因为这必须与sequence
上面的类型匹配,所以我们得到
[b] = [f a]
c = f [a]
因此,b = f a
和
_hole (:) :: f a -> f [a] -> f [a]
pure [] :: f [a]
pure []
零件类型按原样检查。另一方面,我们需要
_hole :: (type of (:)) -> f a -> f [a] -> f [a]
即因为(:) :: d -> [d] -> [d]
对于任何d
,我们得到
_hole :: (d -> [d] -> [d]) -> f a -> f [a] -> f [a]
哪里d
可以随便挑。但是,选择 是“自然的”,d=a
因此我们得到
_hole :: (a -> [a] -> [a]) -> f a -> f [a] -> f [a]
现在,我们需要用_hole f x y = ??
和<$>
来定义<*>
。liftA2
本质上,我们需要从库中重新实现。您现在应该能够解决最后一部分。
推荐阅读
- symfony - 无法使用路由
- r - R相当于SAS“合并”“按”
- c# - C#通过反射按子属性排序父对象列表
- r - 哪个()不匹配给定的行到数据框的行
- c - 为什么 GCC 9.1.0 有时会抱怨这种 strncpy() 的使用?
- c# - 为什么我添加新用户的代码不起作用,它只读取用于检查 ID 是否存在于数据库中的代码?
- python - 如何将类对象转换为命名元组?
- java - ORA-00904: "BOOKORDERS": Hibernate 中的标识符无效
- protractor - 无效参数:尝试上传文件时找不到文件错误
- windows-installer - 如何停止在 InstallShield 中记录 XMLFileChanges?