Implementing this monad/type in Haskell?

2019-05-14 14:42发布

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?

1条回答
孤傲高冷的网名
2楼-- · 2019-05-14 15:04

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 fields x and dataval (where x is a Double and dataval is a Complex Double.

data DataPoint a = DataPoint {x :: Double,
                              dataval :: a}

instance Functor DataPoint where
    fmap f dataPoint = DataPoint {x = x dataPoint,
                                  dataval = f (dataval dataPoint)}
查看更多
登录 后发表回答