And, well, I've stumbled upon some problem with types. Consider a type for a cons list expressed in CPS:
type List a = ((STM (), (a, List a) -> STM ()) -> STM ())
The first STM () gets executed in case of Nil, the second in case of Cons (getting a pair of car and cdr).
Unfortunately, this type fails to check in Haskell. I have to grok yet why, and how to work around it. I would hate to use data:
data List a = List ((STM (), (a, List a) -> STM ()) -> STM ())
as this would reduce clarity by boxing unboxing. Compare:
makeNil :: List a
makeNil (caseNil, _) = caseNil
and
makeNil :: List a
makeNil = List $ \(caseNil, _)->caseNil
Then again, if I shoot for terseness, then nothing beats:
makeNil :: List a
makeNil = List fst
Envisioning code generation for algebraic data types, I arrive to:
type Cont a = a -> STM ()
type CaseNil = Cont ()
type CaseCons a = Cont (a, List a)
data List a = List {unList :: Cont (CaseNil, CaseCons a)}
makeNil :: () -> List a
makeNil payLoad = List $ \(caseNil, _) -> caseNil payLoad
makeCons :: (a, List a) -> List a
makeCons payLoad = List $ \(_, caseCons) -> caseCons payLoad
Hmm, I should consider using currying, after all...
1 comment:
Hi Andris, please see
this.
I'd appreciate it if you'd consider subscribing to e-lang and responding. Thanks.
Post a Comment