I have a type that has a mappend
-like function but not a real mappend
, so it is not a 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
. I need semantics that would be perfectly represented if I could define a Semigroup
instance on the "combined" type Maybe MyType
like this:
instance Semigroup (Maybe MyType) where
(Just x) <> (Just y) = myMerge x y
Nothing <> Nothing = Nothing
Nothing <> (Just _) = Nothing
(Just _) <> Nothing = Nothing
I.e. when both parameters are Just
's, I can get either a Just
or Nothing
, otherwise I always get 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?
A composite data type is constructed from other types. The most common composite data types in Haskell are lists and tuples.
() is very often used as the result of something that has no interesting result. For example, an IO action that is supposed to perform some I/O and terminate without producing a result will typically have type IO () .
Functions can also be passed as arguments or returned (as we have seen). Their types are given in the type signature. *Main> :t map map :: (a -> b) -> [a] -> [b] *Main> :t filter filter :: (a -> Bool) -> [a] -> [a] flip_args :: (a -> b -> c) -> b -> a -> c flip_args f x y = f y x.
In Haskell, types are how you describe the data your program will work with.
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. Instead, use a newtype wrapper:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With