在Haskell中,是否可以为自定义数据类型定义自己的++
运算符?
我的代码如下:
data MyType = MyType [String]
我想定义自己的连接运算符,如下所示:
instance ? MyType where
(MyType x) ++ (MyType y) = MyType (x ++ y)
我似乎找不到实例类的名称。
如果您不坚持称呼运算符(++)
,
import Data.Monoid
instance Monoid MyType where
(MyType x) `mappend` (MyType y) = MyType (x ++ y)
mempty = MyType []
然后你可以使用
(<>) :: Monoid m => m -> m -> m
这是 mappend
的别名(我以为它已经是类型类成员了,但事实并非如此 :/)。列表拥有一个 Monoid
实例,其中 mappend
是 (++)
,所以这将会实现你想要的功能。 Monoid
实例还提供了
mconcat :: Monoid m => [m] -> m
你可以使用它来连接一系列MyType
。import Prelude hiding ((++))
import qualified Prelude as P
data MyType = MyType [String]
class PlusAble a where
infixr 5 ++
(++) :: a -> a -> a
instance PlusAble MyType where
(MyType x) ++ (MyType y) = MyType (x P.++ y)
-- EDIT:
instance PlusAble [a] where
x ++ y = x P.++ y
(++)
运算符不属于任何类型类。你可以轻松地检查这个问题:
$ ghci
Prelude> :info (++)
(++) :: [a] -> [a] -> [a] -- Defined in `GHC.Base'
infixr 5 ++
所以,这只是在 GHC.Base
模块中定义的简单函数。您可以隐藏它并定义自己的函数:
import Prelude hiding ((++))
import qualified Prelude -- to get hidden (++) as Prelude.(++)
-- your brand new (++)
infixr 5 ++
(MyType x) ++ (MyType y) = MyType (x Prelude.++ y)
Monoid
类型类。 - epsilonhalbe(<>)
但没有mempty
,那么您的类型可能是semigroup。不幸的是,Semigroup
目前不是Monoid
的超类。 - shachaf