Type Operator

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Type Operator

Kellen J. McClain
I have a quick question.

Recall that:
class Monad m where
        (>>=) :: m a -> (a -> m b) -> m b
        ...

and suppose I have a data type Sample:

data Sample a b = ...

how could I define Sample to be an instance of Monad such that:

(>>=) :: Sample a c -> (a -> Sample b c) -> Sample b c

?

I would like to use a (\a -> ...)-like operator, but for types.
So, something like this:

instance Monad (\a -> Sample a c) where
        (>>=) :: Sample a c -> (a -> Sample b c) -> Sample b c
        a >>= f = ...

but that obviously doesn't work. Alternatively I would
like to use a type declaration and partially apply it:

type SampleFlip b a = Sample a b
instance Monad (SampleFlip c) where
        (>>=) :: SampleFlip c a -> (a -> SampleFlip c b) -> SampleFlip c b

which translates to:

        (>>=) :: Sample a c -> (a -> Sample b c) -> Sample b c

But this doesn't work either, and ghc extensions don't add this functionality.  
Can I do this in Haskell?

Reply | Threaded
Open this post in threaded view
|

Type Operator

Daniel Fischer-4
Am Mittwoch, 21. Januar 2009 23:30 schrieb Kellen J. McClain:

> I have a quick question.
>
> Recall that:
> class Monad m where
> (>>=) :: m a -> (a -> m b) -> m b
> ...
>
> and suppose I have a data type Sample:
>
> data Sample a b = ...
>
> how could I define Sample to be an instance of Monad such that:
>
> (>>=) :: Sample a c -> (a -> Sample b c) -> Sample b c
>
> ?
>
> I would like to use a (\a -> ...)-like operator, but for types.
> So, something like this:
>
> instance Monad (\a -> Sample a c) where
> (>>=) :: Sample a c -> (a -> Sample b c) -> Sample b c
> a >>= f = ...
>
> but that obviously doesn't work. Alternatively I would
> like to use a type declaration and partially apply it:
>
> type SampleFlip b a = Sample a b
> instance Monad (SampleFlip c) where
> (>>=) :: SampleFlip c a -> (a -> SampleFlip c b) -> SampleFlip c b
>
> which translates to:
>
> (>>=) :: Sample a c -> (a -> Sample b c) -> Sample b c
>
> But this doesn't work either, and ghc extensions don't add this
> functionality. Can I do this in Haskell?
>
I think you can't.
If it's possible, the best option would be to change the order of type
parameters of Sample. If that's not possible, you can define

newtype FSample b a = FS (Sample a b)

and make that an instance of Monad.

Somebody remind me, why does Haskell not have type-lambdas?
Reply | Threaded
Open this post in threaded view
|

Type Operator

Brent Yorgey-2
On Wed, Jan 21, 2009 at 11:51:26PM +0100, Daniel Fischer wrote:
> I think you can't.
> If it's possible, the best option would be to change the order of type
> parameters of Sample. If that's not possible, you can define
>
>   newtype FSample b a = FS (Sample a b)
>
> and make that an instance of Monad.

Right, Haskell doesn't allow partially applied type synonyms, but
partially applied newtypes are fine.  It will just be a bit annoying
having the FS constructor tags everywhere.  Switching the order of the
parameters to Sample would be the best option.

> Somebody remind me, why does Haskell not have type-lambdas?

Because type-lambdas would require higher-order unification during
type checking, which is in general undecidable.  Without type lambdas,
if you have to unify two type applications like

  f a == m b

then you know that f == m and a == b.  But with type lambdas this
might not be the case.  For example, you could have f == \x -> [x], a
= Int, m = \x -> x, and b = [Int].

-Brent