-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathadder.hs
54 lines (41 loc) · 1.62 KB
/
adder.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
-- related to http://stackoverflow.com/questions/29487773/how-to-build-a-typed-variadic-function-from-a-container
{-# LANGUAGE GADTs, KindSignatures, DataKinds, PolyKinds, TypeFamilies, TypeOperators, UndecidableInstances #-}
type family If b x y where
If True x y = x
If False x y = y
data Booly :: Bool -> * where
Truly :: Booly True
Falsy :: Booly False
data Nat = Z | S Nat
data Natty :: Nat -> * where
Zy :: Natty Z
Sy :: Natty n -> Natty (S n)
data Listy (b :: a -> *) :: [a] -> * where
Nilly :: Listy b '[]
Consy :: b x -> Listy b xs -> Listy b (x ': xs)
type Natties = Listy Natty
type family NatEq n m :: Bool where
NatEq Z Z = True
NatEq Z (S m) = False
NatEq (S n) Z = False
NatEq (S n) (S m) = NatEq n m
type family Adder (ns :: [Nat]) :: * where
Adder '[] = Int
Adder (n ': ns) = If (NatEq n (S (S (S (S (S Z)))))) Int (Int -> Adder ns)
nattyEq :: Natty n -> Natty m -> Booly (NatEq n m)
nattyEq Zy Zy = Truly
nattyEq Zy (Sy m) = Falsy
nattyEq (Sy n) Zy = Falsy
nattyEq (Sy n) (Sy m) = nattyEq n m
adder :: Natties ns -> Adder ns
adder = go 0 where
go :: Int -> Natties ns -> Adder ns
go i Nilly = 0
go i (Consy n ns) = case nattyEq n (Sy (Sy (Sy (Sy (Sy Zy))))) of
Truly -> i + 100
Falsy -> \a -> go (i + a) ns
list = Consy Zy $ Consy (Sy Zy) $ Consy (Sy (Sy (Sy (Sy (Sy Zy))))) $ Consy Zy $ Nilly
main = do
print $ adder (Consy Zy $ Consy (Sy Zy) $ Nilly) 3 9 -- 0
print $ adder list 6 8 -- 114
print $ adder (Consy (Sy (Sy Zy)) list) 1 2 3 -- 106