tag:blogger.com,1999:blog-3525174544175275879.post7787312930497427947..comments2012-01-11T12:25:38.385+02:00Comments on Yet another defunct blog: Haskell puzzle: Either monadRoman Cheplyakahttp://www.blogger.com/profile/07189392968519496723noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-3525174544175275879.post-78705742726902478542008-09-11T10:58:00.000+03:002008-09-11T10:58:00.000+03:00Yet another take on why it seems like it should wo...Yet another take on why it seems like it should work, and yet doesn't: a value |Left a| is of type |Either a b| where |b| is a phantom type. Given this, it would be nice to have the value be typed as |forall b. Either a b| so that we can freely cast the phantoms around[1]. However, in Haskell's type system we can't do this, so we need to deconstruct and reconstruct the Either value in order to change the phantom.<BR/><BR/>[1] As I've discussed here: http://winterkoninkje.livejournal.com/56979.html One thing that should be borne in mind about that post, is that it is prudent to distinguish these refinement phantom types from true phantom types ---which we don't want to freely cast, since they carry semantic information.wrenhttp://www.blogger.com/profile/05766067924472271354noreply@blogger.comtag:blogger.com,1999:blog-3525174544175275879.post-33676630287334672672008-09-09T21:21:00.000+03:002008-09-09T21:21:00.000+03:00I know you said "minimal changes", but I...I know you said "minimal changes", but I prefer the pattern match (which also does type check):<BR/><BR/>instance Monad (Either a) where<BR/> return = Right<BR/> Left x >>= _ = Left x<BR/> Right y >>= f = f ydinohttp://www.blogger.com/profile/16345864144713728626noreply@blogger.comtag:blogger.com,1999:blog-3525174544175275879.post-24252140235554597642008-09-09T18:17:00.000+03:002008-09-09T18:17:00.000+03:00A long-winded explanation:Just infer a type for (&...A long-winded explanation:<BR/><BR/>Just infer a type for (>>=):<BR/>Either a b1 -> (b1 -> Either a b2) -> Either a b2<BR/><BR/>So types don't much:<BR/>Either a b1 /= Either a b2<BR/><BR/>So (>>=) may not return its first argument. But you can construct 'Either a b2' from 'a'.beroalhttp://beroal.livejournal.com/noreply@blogger.comtag:blogger.com,1999:blog-3525174544175275879.post-60376439435429417892008-09-09T15:31:00.000+03:002008-09-09T15:31:00.000+03:00Bonus, I think it has to do with the unification a...Bonus, I think it has to do with the unification algorithm.<BR/><BR/>(>>=) :: m a -> (a -> m b) -> m b<BR/><BR/>The type checker has already determined that the variable 'x' is of type 'm a', or 'Either l a', and we need to return an 'm b' or 'Either l b'. So we need to recreate the Left so we get a fresh variable to type check against.Bryanhttp://www.blogger.com/profile/00161448428728145065noreply@blogger.comtag:blogger.com,1999:blog-3525174544175275879.post-80725308794007579242008-09-09T13:54:00.000+03:002008-09-09T13:54:00.000+03:00I kind of thought it was going to be Left a -> ...I kind of thought it was going to be Left a -> Left a, probably because of the way Left _ would behave on Left undefined, however, I'm not sure exactly why this does not typecheck and Left a -> Left a does, anyone care to elaborate?Bonushttp://www.blogger.com/profile/02725486955962218311noreply@blogger.comtag:blogger.com,1999:blog-3525174544175275879.post-33979387037843909602008-09-07T20:41:00.000+03:002008-09-07T20:41:00.000+03:00Correct :)Correct :)Roman Cheplyakahttp://www.blogger.com/profile/07189392968519496723noreply@blogger.comtag:blogger.com,1999:blog-3525174544175275879.post-59952521415742286702008-09-07T20:38:00.000+03:002008-09-07T20:38:00.000+03:00let me guess...Left a -> Left a?let me guess...<BR/><BR/>Left a -> Left a<BR/><BR/>?e.v.ehttp://www.blogger.com/profile/13164706078167130240noreply@blogger.com