Haskell 教程(https://www.fpcomplete.com/haskell/tutorial/monad-transformers/)说,如果我们假设以下定义
newtype State s a = State (s -> (s, a))
Run Code Online (Sandbox Code Playgroud)
那么下面的定义
newtype StateEither s e a = StateEither (State s (Either e a))
Run Code Online (Sandbox Code Playgroud)
是一个重写
newtype StateEither s e a = StateEither (s -> (s, Either e a))
Run Code Online (Sandbox Code Playgroud)
哪些替代步骤使这成为可能?
两者并不是彼此的重写:类型检查器不会推断出两者是相同的。然而两者非常相似。
事实上,该State类型定义为:
newtype State s a = State (s -> (s, a))
Run Code Online (Sandbox Code Playgroud)
这意味着对于 a State s a,它将函数包装s -> (a, s)到数据构造函数中State。如果我们因此删除State数据构造函数,我们可以将其视为类型为 的函数s -> (a, s),因此:
type State s a = s -> (s, a)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,类型State s (Either e a)因此具有类型:
s -> (s, Either e a)
Run Code Online (Sandbox Code Playgroud)
所以:
newtype StateEither s e a = StateEither (State s (Either e a))
Run Code Online (Sandbox Code Playgroud)
相当于:
newtype StateEither s e a = StateEither (s -> (s, Either e a))
Run Code Online (Sandbox Code Playgroud)
newtype然而这里使用了a 。这对于为类型类定义不同的实例很有用,因为函数也是 a 的实例Monad,但我们想instance为Monada定义不同的实例State。