我试图利用Semigroup类型化来玩玩单子,并且我试图在自然数上定义一个单子。我将以下类和实例声明放入GHCI中
Prelude:{
Prelude| class Semigroup a where
Prelude| (<>) :: a -> a -> a)
Prelude| newtype Sum a = Sum { getSum :: a }
Prelude| deriving (Eq, Ord, Show)
Prelude| instance Num a => Monoid (Sum a) where
Prelude| (<>) = coerce ((+) :: a -> a -> a)
Prelude| instance Num a => Monoid (Sum a) where
Prelude| mempty = Sum 0
Prelude| :} 我收到这样的信息:
<interactive>:7:4: error:
Ambiguous occurrence ‘<>’
It could refer to either ‘Prelude.<>’,
imported qualified from ‘Prelude’
(and originally defined in ‘GHC.Base’)
or ‘<>’, defined at <interactive>:3:4然后我输入了import qualified Prelude as P,以避免冲突,但这不起作用,我得到了错误消息:
code<interactive>:26:19: error:
Not in scope: type constructor or class ‘Monoid’
Perhaps you meant one of these:
‘P.Monoid’ (imported from Prelude),
‘P.Monad’ (imported from Prelude) 发布于 2020-07-11 11:06:50
你不应该自己定义类型。它已经被定义了,通过定义另一个函数,这意味着您的所有(<>)函数等等现在都可以指向您定义的Semigroup或在Prelude中定义的那个。
因此,您可以定义您的类型并使其成为Semigroup和Monoid的实例,并使用:
import Data.Semigroup
newtype Sum a = Sum { getSum :: a } deriving (Eq, Ord, Show)
instance Num a => Semigroup (Sum a) where
Sum a <> Sum b = Sum (a + b)
instance Num a => Monoid (Sum a) where
mempty = Sum 0
mappend = (<>)因此,如果我们在shell中运行这个程序,就会得到:
Prelude> import Data.Semigroup
Prelude Data.Semigroup> :{
Prelude Data.Semigroup| newtype Sum a = Sum { getSum :: a } deriving (Eq, Ord, Show)
Prelude Data.Semigroup|
Prelude Data.Semigroup| instance Num a => Semigroup (Sum a) where
Prelude Data.Semigroup| Sum a <> Sum b = Sum (a + b)
Prelude Data.Semigroup|
Prelude Data.Semigroup| instance Num a => Monoid (Sum a) where
Prelude Data.Semigroup| mempty = Sum 0
Prelude Data.Semigroup| mappend = (<>)
Prelude Data.Semigroup| :}
Prelude Data.Semigroup> Sum 0 <> Sum 1 <> Sum 4 <> Sum 5
Sum {getSum = 10}https://stackoverflow.com/questions/62848292
复制相似问题