'Monad (Writer String)' 的非法实例声明
Illegal instance declaration for 'Monad (Writer String)'
我尝试创建自己的 Writer 类型,之后我也为它创建了一个实例。不管怎样,我一直收到这个错误:
Illegal instance declaration for ‘Monad (Writer String)’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
In the instance declaration for ‘Monad (Writer String)’
这是我的代码:
newtype Writer log a = Writer {runWriter :: (a,log)}
instance Monad (Writer String) where
return a = Writer (a, "")
ma >>= k = let (a, log1) = runWriter ma
(b, log2) = runWriter (k a)
in Writer (b, log1 ++ log2)
All instance types must be of the form (T a1 ... an)
...意思是,你可以写
instance Monad (Writer a) where ...
但不是
instance Monad (Writer String) where ...
因为String
不是类型变量。
这只是 Haskell 自 Haskell98 以来的愚蠢限制标准。显然,该限制使编写编译器变得更容易,我不知道。每个人都使用 FlexibleInstances
扩展,它已经在 GHC 中使用了很长时间并禁用了限制。
{-# LANGUAGE FlexibleInstances #-}
newtype Writer log a = Writer {runWriter :: (a,log)}
instance Monad (Writer String) where
...
或者,您可以使用更多的多态实例,但 Monad (Writer a)
不太有效,因为您需要能够拥有空日志和连接日志。标准解决方案是为可连接类型调用泛型 class:
import Data.Monoid
instance <b>Monoid a =></b> Monad (Writer a) where
return a = Writer (a, <b>mempty</b>)
ma >>= k = let (a, log1) = runWriter ma
(b, log2) = runWriter (k a)
in Writer (b, log1 <b><></b> log2)
另一方面,要获得 Monad
实例,您还必须首先实例化 Applicative
。
我尝试创建自己的 Writer 类型,之后我也为它创建了一个实例。不管怎样,我一直收到这个错误:
Illegal instance declaration for ‘Monad (Writer String)’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
In the instance declaration for ‘Monad (Writer String)’
这是我的代码:
newtype Writer log a = Writer {runWriter :: (a,log)}
instance Monad (Writer String) where
return a = Writer (a, "")
ma >>= k = let (a, log1) = runWriter ma
(b, log2) = runWriter (k a)
in Writer (b, log1 ++ log2)
All instance types must be of the form (T a1 ... an)
...意思是,你可以写
instance Monad (Writer a) where ...
但不是
instance Monad (Writer String) where ...
因为String
不是类型变量。
这只是 Haskell 自 Haskell98 以来的愚蠢限制标准。显然,该限制使编写编译器变得更容易,我不知道。每个人都使用 FlexibleInstances
扩展,它已经在 GHC 中使用了很长时间并禁用了限制。
{-# LANGUAGE FlexibleInstances #-}
newtype Writer log a = Writer {runWriter :: (a,log)}
instance Monad (Writer String) where
...
或者,您可以使用更多的多态实例,但 Monad (Writer a)
不太有效,因为您需要能够拥有空日志和连接日志。标准解决方案是为可连接类型调用泛型 class:
import Data.Monoid
instance <b>Monoid a =></b> Monad (Writer a) where
return a = Writer (a, <b>mempty</b>)
ma >>= k = let (a, log1) = runWriter ma
(b, log2) = runWriter (k a)
in Writer (b, log1 <b><></b> log2)
另一方面,要获得 Monad
实例,您还必须首先实例化 Applicative
。