haskell - 如何修改类型声明,这样我们就不必将 Either 更改为类型构造函数?
问题描述
{- data Either e a = Left e | Right a
from the standard library.
It's like Maybe, but the "no answer" case carries extra data, perhaps some kind
of reason for why "no answer".
-}
fmap_Either :: (a -> b) -> (Either e) a -> (Either e) b
fmap_Either f (Left e) = Left e
fmap_Either f (Right a) = Right (f a)
这是我讲座中的一个例子。由于该函数只接受一个参数a
,因此输出将变为 type b
。我们必须更改Either e a
为类型构造函数(Either e) a
。我想知道我们是否可以修改函数,它将接受 2 个参数,以便我们可以编写Either e a
而不是(Either e) a
. 虽然我不确定这是否是个好主意。
解决方案
我们可以修改函数吗,它将接受 2 个参数,以便我们可以编写
Either e a
而不是(Either e) a
. 虽然我不确定这是否是个好主意。
情况已经如此,在HaskellEither e a
中与(Either e) a
. 前者只是去除了一些“噪音”,但如果你在窗帘后面写Either e a
,你实际上已经写了(Either e) a
。
在 Haskell 中,每个函数都只接受一个参数。这也适用于类型构造函数:类型构造函数采用一个类型参数。如果我们因此编写需要两个或更多类型参数的类型,我们实际上已经编写了一个类型构造函数,它接受一种类型并生成一个新的“类型构造函数”,它将接受其他参数。
这个概念实际上在类型类中经常使用。以Functor
类型类(定义fmap
函数的类型类)为例:
class Functor f where fmap :: (a -> b) -> f a -> f b (<$) :: a -> f b -> f a (<$) = fmap . const
我们在这里看到这f
是一个接受类型参数的类型构造函数,因为在类型类的主体中,我们创建了类型f a
和f b
。
如果我们再看看我们看到的Functor
实例Either
:
instance Functor (Either e) where fmap _ (Left x) = Left x fmap f (Right y) = Right (f y)
(我替换(Either a)
为,(Either e)
因为声明中的 与定义中的不同a
,因此避免混淆)instance
a
class
所以这里f
是Either e
,因此f a
将是一个(Either e) a
或Either e a
。
推荐阅读
- javascript - 循环更改文档中的所有 alt="" 值
- prolog - Prolog 变量没有按预期统一
- c++ - WinApi压缩、python3中的解压
- loops - WaitGroup 不受双重尊重
- cpu - 测试 XDP 与 DPDK
- flow-project - tutorial03_rlib 中的错误
- javascript - 当函数内部不使用事件参数时,为什么这个handleBlur函数带有事件参数?
- asp.net - 调试器是否有可能同时运行两次?
- python - 在这段代码中,我得到 UnboundLocalError: local variable 'click' referenced before assignment。我不知道为什么?
- javascript - next.js、javascript、graphql、react js 中的 Apollo 客户端问题