
Hello all, Looking at the OOHaskell black (grey?) magic, and wondering if there would be an interesting way to construct class interfaces using the OOHaskell paradigm? I'm trying to do it as so (assume relevant types/proxies declared): type FigureInter = Record ( Draw :=: IO () :*: HNil ) figure self = do return emptyRecord where _ = narrow self :: FigureInter abstrFigure self = do super <- figure self visible <- newIORef True returnIO $ setVisible .=. (\b -> writeIORef visible b) .*. isVisible .=. readIORef visible .*. draw .=. return () .<. super but ghci complains (you know how it likes to complain), with Couldn't match expected type `Record t2' against inferred type `F (Proxy Draw) (m ())' In the second argument of `(.*.)', namely `draw .=. (return ())' In the second argument of `(.*.)', namely `(isVisible .=. (readIORef visible)) .*. (draw .=. (return ()))' In the first argument of `(.<.)', namely `(setVisible .=. (\ b -> writeIORef visible b)) .*. ((isVisible .=. (readIORef visible)) .*. (draw .=. (return ())))' Anyone have any tips they care to share? :) Scott

I conquered the below problem, but now I have another question:
How can one have two interface-classes that reference each other? For example,
type Inter1 = Record (
MkFoo :=: Inter2 -> IO ()
:*: HNil )
type Inter2 = Record (
MkBar :: Inter1 -> IO ()
:*: HNil )
Obviously this is cyclical, but is there a nice way to get around it?
I think I could wrap them up in a datatype (ie, data InterOne =
InterOne Inter1, and modify definitions accordingly) but are there any
alternative methods?
Scott
On 7/6/07, Scott West
Hello all,
Looking at the OOHaskell black (grey?) magic, and wondering if there would be an interesting way to construct class interfaces using the OOHaskell paradigm?
I'm trying to do it as so (assume relevant types/proxies declared):
type FigureInter = Record ( Draw :=: IO () :*: HNil )
figure self = do return emptyRecord where _ = narrow self :: FigureInter
abstrFigure self = do super <- figure self visible <- newIORef True returnIO $ setVisible .=. (\b -> writeIORef visible b) .*. isVisible .=. readIORef visible .*. draw .=. return () .<. super
but ghci complains (you know how it likes to complain), with
Couldn't match expected type `Record t2' against inferred type `F (Proxy Draw) (m ())' In the second argument of `(.*.)', namely `draw .=. (return ())' In the second argument of `(.*.)', namely `(isVisible .=. (readIORef visible)) .*. (draw .=. (return ()))' In the first argument of `(.<.)', namely `(setVisible .=. (\ b -> writeIORef visible b)) .*. ((isVisible .=. (readIORef visible)) .*. (draw .=. (return ())))'
Anyone have any tips they care to share? :)
Scott

On Fri, Jul 06, 2007 at 06:11:42PM -0400, Scott West wrote:
I conquered the below problem, but now I have another question:
How can one have two interface-classes that reference each other? For example,
type Inter1 = Record ( MkFoo :=: Inter2 -> IO () :*: HNil )
type Inter2 = Record ( MkBar :: Inter1 -> IO () :*: HNil )
Obviously this is cyclical, but is there a nice way to get around it? I think I could wrap them up in a datatype (ie, data InterOne = InterOne Inter1, and modify definitions accordingly) but are there any alternative methods?
In Haskell type synonyms can't be recursive. You can use a newtype - the wrapper has no runtime cost, it's just an instruction to the typechecker, much like the explicit rolling and unrolling in an "isorecursive" treatment of recursive types. I think it's about as easy to build a typesystem with recursive types, the problem is that a lot of bogus programs typecheck. See http://www.haskell.org/pipermail/haskell-cafe/2006-December/020074.html Matthias Blume et. al. have made a language called MLPolyR with extensible records and variants (with case expressions and exception handling built from them), and report that it works pretty well to infer infinite types only if they recurse through a record or variant type. Brandon
participants (2)
-
Brandon Michael Moore
-
Scott West