-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSLP.hs
67 lines (56 loc) · 1.37 KB
/
SLP.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
{-# LANGUAGE BangPatterns #-}
module SLP
( SLP(..)
, toIDL
, appSLP
, singSLP
, P(..)
) where
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import Unsafe.Coerce
data P = P {-# UNPACK #-} !Int {-# UNPACK #-} !Double
data SLP
= Nil
| Cns {-# UNPACK #-} !P SLP
lenSLP :: SLP -> Int
lenSLP sls = go 0 sls
where
go !ct (Cns _ tl) = go (ct+1) tl
go ct Nil = ct
revSLP :: SLP -> SLP
revSLP sls = go Nil sls
where
go !acc (Cns p tl) = go (Cns p acc) tl
go acc Nil = acc
appSLP :: SLP -> SLP -> SLP
appSLP Nil l = l
appSLP l Nil = l
appSLP (Cns p tl) l = Cns p (go tl)
where
go Nil = l
go (Cns q u) = Cns q (go u)
singSLP :: Int -> Double -> SLP
singSLP i d = Cns (P i d) Nil
instance Binary SLP where
put sls = do
let go (Cns p tl) = put p >> go tl
go Nil = return ()
put (lenSLP sls) >> go sls
get = do
len <- get :: Get Int
let go acc 0 = return $! revSLP acc
go !acc k = do
p <- get
go (Cns p acc) (k-1)
go Nil len
instance Binary P where
put (P i f) = putWord64be (fromIntegral i) >> putWord64be (unsafeCoerce f)
get = do
!i <- fmap fromIntegral getWord64be
!f <- fmap unsafeCoerce getWord64be
return $ P i f
toIDL :: SLP -> [(Int,Double)]
toIDL (Cns (P i f) tl) = (i,f):toIDL tl
toIDL _ = []