-
Notifications
You must be signed in to change notification settings - Fork 1
/
rwh04.hs
98 lines (80 loc) · 2.91 KB
/
rwh04.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
-- RWH Chapter 4. Functional programming --
import Control.Exception (assert)
-- Better to use `null' than `length', because of the lazy evaluation
-- Or, pattern matching is also a good idea (which actually resembles
-- what `null' does, so less readable)
-- This sucks on infinite lists, also decrease performance on long lists
safeHeadDumb xs = if length xs > 0
then Just $ head xs
else Nothing
safeHead xs
| null xs = Nothing
| otherwise = Just $ head xs
safeHead' [] = Nothing
safeHead' xs = Just $ head xs
-- Partial / total functions (think of `totality' in Idris)
-- `and', `or', `all', `any' on empty list
-- Be careful! Assertion is done when you need its value!
andEmpty = assert (and []) True
orEmpty = assert (not $ or []) False
-- Usefull functions dealing with strings
cutByLine = lines "multi\nline\ntext"
concatByLine = unlines ["multi", "line", "text"]
cutBySpace = words "Can \ryou\nhear\t me,\r\n Alice?"
concatBySpace = unwords ["Can", "you", "hear", "me,", "Alice?"]
-- Furthermore:
-- `take', `drop' and `takeWhile', `dropWhile'
-- `splitAt' "tuples up" the results of `take' and `drop'
-- `span' "tuples up" those of `takeWhile'
-- `break' "tuples up" those of `dropWhile'
-- Further further more:
-- from Data.List: `nub', `group', `sort'
-- ex02, both work
splitWith :: (a -> Bool) -> [a] -> [[a]]
splitWith _ [] = []
--splitWith p all@(x:xs) = case break p all of
-- ([] , _ ) -> splitWith p xs
-- (first, rest) -> first : splitWith p rest
-- `dropWhile null' to remove null list at the head brought by `break'
splitWith p (x:xs) = dropWhile null $ first : restSplit
where (first, rest) = break p (x:xs)
restSplit = splitWith p $ dropWhile p rest
-- Failed to get a reasonably working `zipWithN'
-- Further readings:
-- * http://okmij.org/ftp/Haskell/polyvariadic.html
-- * https://stackoverflow.com/questions/20558648/what-is-the-datakinds-extension-of-haskell
-- * https://www.reddit.com/r/haskell/comments/b9qyp/generalized_zipwithn_with_a_pretty_implementation/
{-
--data Z
--data S n
class NatureNum a where
fromNum :: Integral b => b -> a
toNum :: Integral b => a -> b
--data Nat n where
-- Zero :: Nat Z
-- Succ :: Nat n -> Nat (S n)
data Nat = Z | S Nat
--instance NatureNum (Nat) where
-- toNum Z = 0
-- toNum (S n) = 1 + toNum n
--instance NatureNum Zero where
-- fromNum _ = Zero
-- toNum _ = 0
--instance NatureNum (Succ n) where
-- fromNum _ = Succ Zero
-- toNum _ = 1
--fromNum :: Integral a => a -> (Nat n)
--fromNum 0 = Zero
----fromNum k = Succ ( fromNum (k-1))
--fromNum 1 = Succ Zero
--data NArgsFunc a :: Nat -> * where
-- NArgsFunc ::
--data NArgsFunc a = ZeroArgFunc a
-- | NArgsFunc a (NArgsFunc a)
type ZeroArgFunc a = a
testZ :: (ZeroArgFunc Int)
testZ = (42)
type NArgsFunc Nat a = a -> (NArgsFunc Z
test1 :: (NArgsFunc [Char] (ZeroArgFunc Int))
test1 = length
-}