1

I was working through LYAH and I wanted to extend on the Type-foo chapter. I came up with the following type:

data Frank a b = Frank {first :: a b, second :: b}
-- Frank :: (* -> *) -> * -> *
-- Frank :: a b -> b -> Frank a b

And I wanted to make it an instance of the Tofu class:

class Tofu t where          -- Tofu :: ((* -> *) -> * -> *) -> Constraint
    tofu :: a b -> t a b

Can anyone come up with a simple instance?

wdeweijer
  • 13
  • 4
  • 3
    As stated, it's provably impossible. There are no functions `Const () Void -> Frank (Const ()) Void`, except for non-terminating ones (at least for field `second`). Concretely, `tofu` needs a way to generate a `b` from its inputs, which is currently impossible. – chi Feb 15 '15 at 22:16
  • Another observation: assume that you could do this. Then, in the body of `Frank`'s implementation of `tofu`, you would take a type-constructed thing `a b` and somehow pull out just the `b` part. So imagine if `a` was a Monad. Then some function used inside of `tofu` would have to have type `a b -> b` (where `a` can be a Monad but doesn't have to be one). See [here for a discussion](http://stackoverflow.com/questions/8567743/how-to-extract-value-from-monadic-action) of why such a function is not generally possible. – ely Feb 15 '15 at 22:59
  • While this doesn't totally rule out the possibility, it would mean that `Frank` can't make use of Monad types for "a", which would be extremely limiting. – ely Feb 15 '15 at 22:59

0 Answers0