Reputation: 13600
I really cannot figure out the syntax necessary for this, and it probably comes from my lack of understanding of how types work.
I want a type DataPoint
, which stores either a tuple (x, dataval)
or two fields x and dataval (where x is a Double
and dataval is a Complex Double
.
I want a Monad
instance where it goes something like:
instance Monad (DataPoint x dataval) where
return dataval = DataPoint 0.0 dataval
DataPoint x dataval >>= f = DataPoint x (f dataval)
Basically, the "value" of the monad is dataval, and x is just a part of the container.
I don't think my syntax is correct though. If i define DataPoint as
data DataPoint x dataval = DataPoint { x :: Double
, dataval :: Complex Double }
then it should work, right?
Only I get a "kind mismatch"
The first argument of `Monad' should have kind `* -> *',
but `DataPoint x dataval' has kind `*'
Can anyone help me get the functionality/monad I am trying to acheive?
Upvotes: 3
Views: 878
Reputation: 47052
In terms of syntax, it's
instance Monad (DataPoint x) where
-- etc
Although I share hammar's concerns and think you should be trying to make it a Functor instead:
instance Functor (DataPoint x) where
-- etc
The kind error you get
The first argument of `Monad' should have kind `* -> *',
but `DataPoint x dataval' has kind `*'
is because Monad
and Functor
are typeclasses that apply to higher order types (compare with Monoid
, a typeclass that applies to simple types).
e.g. IO Int
is not a monad; IO ()
is not a monad; IO
is a monad.
I want a type
DataPoint
, which stores either a tuple(x, dataval)
or two fieldsx
anddataval
(wherex
is aDouble
anddataval
is aComplex Double
.
data DataPoint a = DataPoint {x :: Double,
dataval :: a}
instance Functor DataPoint where
fmap f dataPoint = DataPoint {x = x dataPoint,
dataval = f (dataval dataPoint)}
Upvotes: 7