-
Notifications
You must be signed in to change notification settings - Fork 3
/
examples.hs
79 lines (58 loc) · 2.39 KB
/
examples.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{-# LANGUAGE GADTs, StandaloneDeriving, FlexibleContexts, NamedFieldPuns, RankNTypes, ExistentialQuantification, MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-}
module Examples where
data Thing = Thing { name :: String, info :: Int }
showName (Thing { name = nm }) = nm
showTh th = nm where
Thing { name = nm } = th
shth (Thing {info, name}) = info
data Pun = One { x :: Int, y :: Int } | Two { x :: Int }
--showOther { name = nm } = nm
-- polymorphic recursion
data Expr' key expr = Var key
| App expr expr
newtype Expr key = Expr (Expr' key (Expr key))
{-class Misc a where-}
{-misc :: a -> String-}
{-data (Misc a) => MiscHolder a = MH a-}
{-| MH2 a a-}
{-deriving (Show)-}
{-instance Misc Int where-}
{-misc x = show $ x + 1-}
retident :: Int -> forall a. a -> a
retident 0 = \x -> x
retident _ = fst (retident 0, ((retident 0) 4, (retident 0) 'c'))
-- no need for dependent types for this example
class ApplyTup args func result where
applyTup :: func -> args -> result
instance (a ~ b) => ApplyTup () a b where
applyTup result () = result
instance (ApplyTup b d result, a ~ c) => ApplyTup (a, b) (c -> d) result where
applyTup f (arg, rest) = applyTup (f arg) rest
-- explicit "dictionary-passing" translation
applyTupEx (self, next) f args = self next f args
applyTupUnitMethod () result () = result
applyTupPairMethod (next, cont) f (arg, rest) = next cont (f arg) rest
testMethod = (applyTupPairMethod, (applyTupPairMethod, (applyTupPairMethod, (applyTupUnitMethod, ()))))
testArgs = (True, ((), (4, ())))
testApplyTupEx = applyTupEx testMethod (\x () y -> (x, y)) testArgs
-- gadt translation
data LL r where
LLNil :: LL ()
LLCons :: a -> LL bs -> LL (a, bs)
-- can these be derived?
instance Show (LL ()) where
show LLNil = "LLNil"
instance (Show a, Show (LL bs)) => Show (LL (a, bs)) where
show (LLCons a bs) = "(LLCons " ++ show a ++ " " ++ show bs ++ ")"
-- this does not work
{-deriving instance Show (LL ())-}
{-deriving instance (Show a, Show (LL b)) => Show (LL (a, b))-}
-- cleaner than the class-based version?
type family ApplyFuncLL tup result where
ApplyFuncLL () result = result
ApplyFuncLL (a, b) result = a -> ApplyFuncLL b result
applyLL :: ApplyFuncLL ab result -> LL ab -> result
applyLL f LLNil = f
applyLL f (LLCons a bs) = applyLL (f a) bs
-- applyLL ((,) . (+ 1)) (LLCons 3 (LLCons 'c' LLNil))
-- ===> (4, 'c')