[英]Defining an instance for a composite type in Haskell
I have a type that has a mappend
-like function but not a real mappend
, so it is not a Semigroup
. 我有一个类似mappend
的函数,但不是真正的mappend
,所以它不是Semigroup
。 For instance: 例如:
data MyType = MyType Int deriving Show
myMerge :: MyType -> MyType -> Maybe MyType
myMerge (MyType x) (MyType y)
| (x < 0) || (y < 0) = Nothing
| otherwise = Just $ MyType $ x + y
I always deal with MyType
when it is wrapped in Maybe
. 当它包含在Maybe
时,我总是处理MyType
。 I need semantics that would be perfectly represented if I could define a Semigroup
instance on the "combined" type Maybe MyType
like this: 如果我可以在“组合”类型上定义一个Semigroup
实例,那么我需要能够完美表示的语义。 Maybe MyType
如下:
instance Semigroup (Maybe MyType) where
(Just x) <> (Just y) = myMerge x y
Nothing <> Nothing = Nothing
Nothing <> (Just _) = Nothing
(Just _) <> Nothing = Nothing
Ie when both parameters are Just
's, I can get either a Just
or Nothing
, otherwise I always get Nothing
. 即当两个参数都是Just
,我可以得到Just
或Nothing
,否则我总是得到Nothing
。 But this is not possible, I get an error: 但这是不可能的,我收到一个错误:
All instance types must be of the form (T a1 ... an)
How can I represent the semantics that I need? 我如何表示我需要的语义?
The instance you defined is illegal because it is basically trying to define a different (partial) Semigroup instance for Maybe, but Maybe already has one. 您定义的实例是非法的,因为它基本上是尝试为Maybe定义一个不同的(部分)Semigroup实例,但是Maybe已经有了一个。 Instead, use a newtype wrapper: 相反,使用newtype包装器:
newtype MaybeMyType = MaybeMyType (Maybe MyType)
instance Semigroup MaybeMyType where
...
You will have to interact with your type through this MaybeMyType wrapper in the cases where you want to use its Semigroup instance. 在您想要使用其Semigroup实例的情况下,您必须通过此MaybeMyType包装器与您的类型进行交互。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.