зеркало из
https://github.com/iharh/notes.git
synced 2025-10-29 20:56:06 +02:00
244 строки
5.8 KiB
Plaintext
244 строки
5.8 KiB
Plaintext
1. const
|
|
|
|
const :: a -> b -> a
|
|
const x _ = x
|
|
|
|
|
|
2. flip
|
|
|
|
flip :: (a -> b -> c) -> b -> a -> c
|
|
flip f x y = f y x
|
|
|
|
|
|
Parameters flipping
|
|
|
|
flip' :: (a -> b -> c) -> (b -> a -> c)
|
|
flip' f = g
|
|
where g x y = f y x
|
|
|
|
or
|
|
|
|
flip' f y x = f x y
|
|
|
|
|
|
|
|
|
|
3. enumFromTo
|
|
|
|
class Enum a where
|
|
enumFromTo :: a -> a -> [a]
|
|
enumFromTo x y = map toEnum [fromEnum x .. fromEnum y]
|
|
...
|
|
toEnum :: Int -> a
|
|
fromEnum :: a -> Int
|
|
|
|
-- Used in Haskell's translation of [n..m].
|
|
|
|
|
|
4. until
|
|
|
|
until :: (a -> Bool) -> (a -> a) -> a -> a
|
|
until p f x | p x = x
|
|
| otherwise = until p f (f x)
|
|
|
|
5. uncurry
|
|
|
|
uncurry :: (a -> b -> c) -> ((a, b) -> c)
|
|
uncurry f p = f (fst p) (snd p)
|
|
|
|
|
|
6. elem
|
|
|
|
elem :: (Eq a) => a -> [a] -> Bool
|
|
elem _ [] = False
|
|
elem x (y:ys) = x==y || elem x ys
|
|
|
|
or
|
|
|
|
elem x = any (== x)
|
|
|
|
|
|
7. any, all
|
|
|
|
any :: (a -> Bool) -> [a] -> Bool
|
|
any _ [] = False
|
|
any p (x:xs) = p x || any p xs
|
|
|
|
any p = or . map p
|
|
|
|
all :: (a -> Bool) -> [a] -> Bool
|
|
all _ [] = True
|
|
all p (x:xs) = p x && all p xs
|
|
|
|
all p = and . map p
|
|
|
|
|
|
8. and, or
|
|
|
|
and :: [Bool] -> Bool
|
|
and [] = True
|
|
and (x:xs) = x && and xs
|
|
|
|
and = foldr (&&) True
|
|
|
|
|
|
or :: [Bool] -> Bool
|
|
or [] = False
|
|
or (x:xs) = x || or xs
|
|
|
|
or = foldr (||) False
|
|
|
|
|
|
9. span, break
|
|
|
|
-- | 'span', applied to a predicate @p@ and a list @xs@, returns a tuple where
|
|
-- first element is longest prefix (possibly empty) of @xs@ of elements that
|
|
-- satisfy @p@ and second element is the remainder of the list:
|
|
--
|
|
-- > span (< 3) [1,2,3,4,1,2,3,4] == ([1,2],[3,4,1,2,3,4])
|
|
-- > span (< 9) [1,2,3] == ([1,2,3],[])
|
|
-- > span (< 0) [1,2,3] == ([],[1,2,3])
|
|
--
|
|
-- 'span' @p xs@ is equivalent to @('takeWhile' p xs, 'dropWhile' p xs)@
|
|
|
|
span :: (a -> Bool) -> [a] -> ([a],[a])
|
|
span _ xs@[] = (xs, xs)
|
|
span p xs@(x:xs')
|
|
| p x = let (ys,zs) = span p xs' in (x:ys,zs)
|
|
| otherwise = ([],xs)
|
|
|
|
|
|
10. group, groupBy
|
|
|
|
-- | The 'group' function takes a list and returns a list of lists such
|
|
-- that the concatenation of the result is equal to the argument. Moreover,
|
|
-- each sublist in the result contains only equal elements. For example,
|
|
--
|
|
-- > group "Mississippi" = ["M","i","ss","i","ss","i","pp","i"]
|
|
--
|
|
-- It is a special case of 'groupBy', which allows the programmer to supply
|
|
-- their own equality test.
|
|
group :: Eq a => [a] -> [[a]]
|
|
group = groupBy (==)
|
|
|
|
-- | The 'groupBy' function is the non-overloaded version of 'group'.
|
|
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
|
|
groupBy _ [] = []
|
|
groupBy eq (x:xs) = (x:ys) : groupBy eq zs
|
|
where (ys,zs) = span (eq x) xs
|
|
|
|
|
|
11. composition (.)
|
|
|
|
-- | Function composition.
|
|
-- Make sure it has TWO args only on the left, so that it inlines
|
|
-- when applied to two functions, even if there is no final argument
|
|
(.) :: (b -> c) -> (a -> b) -> a -> c
|
|
(.) f g = \x -> f (g x)
|
|
|
|
|
|
12. application ($)
|
|
|
|
-- | Application operator. This operator is redundant, since ordinary
|
|
-- application @(f x)@ means the same as @(f '$' x)@. However, '$' has
|
|
-- low, right-associative binding precedence, so it sometimes allows
|
|
-- parentheses to be omitted; for example:
|
|
--
|
|
-- > f $ g $ h x = f (g (h x))
|
|
--
|
|
-- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@,
|
|
-- or @'Data.List.zipWith' ('$') fs xs@.
|
|
{-# INLINE ($) #-}
|
|
($) :: (a -> b) -> a -> b
|
|
f $ x
|
|
|
|
Note: f(g(z x)) is equal to f $ g $ z x
|
|
sum(filter (> 10)(map (*2) [2..10)) is equal to sum $ filter (> 10) $ map (*2) [2..10]
|
|
We can even map function application itself
|
|
> map ($ 3) [(4+), (10*), (^2), sqrt]
|
|
[7.0, 30.0, 9.0, 1.732050875688772]
|
|
|
|
> :i ($)
|
|
...
|
|
infixr 0 $
|
|
|
|
|
|
13. on
|
|
|
|
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
|
|
f 'on' g = \x y -> f (g x) (g y)
|
|
|
|
|
|
(.*.) `on` f = \x y -> f x .*. f y.
|
|
|
|
Typical usage: Data.List.sortBy (compare `on` fst).
|
|
|
|
|
|
(==) 'on' (> 0) --- (\x y -> (x > 0) == (y > 0))
|
|
compare 'on' length --- (\x y -> length x 'compare' length y)
|
|
|
|
|
|
14. repeat, iterate, replicate, cycle
|
|
|
|
-- | 'repeat' @x@ is an infinite list, with @x@ the value of every element.
|
|
repeat :: a -> [a]
|
|
{-# INLINE [0] repeat #-}
|
|
-- The pragma just gives the rules more chance to fire
|
|
repeat x = xs where xs = x : xs
|
|
|
|
|
|
-- | 'iterate' @f x@ returns an infinite list of repeated applications
|
|
-- of @f@ to @x@:
|
|
--
|
|
-- > iterate f x == [x, f x, f (f x), ...]
|
|
|
|
iterate :: (a -> a) -> a -> [a]
|
|
iterate f x = x : iterate f (f x)
|
|
|
|
|
|
-- | 'replicate' @n x@ is a list of length @n@ with @x@ the value of
|
|
-- every element.
|
|
-- It is an instance of the more general 'Data.List.genericReplicate',
|
|
-- in which @n@ may be of any integral type.
|
|
{-# INLINE replicate #-}
|
|
replicate :: Int -> a -> [a]
|
|
replicate n x = take n (repeat x)
|
|
|
|
|
|
-- | 'cycle' ties a finite list into a circular one, or equivalently,
|
|
-- the infinite repetition of the original list. It is the identity
|
|
-- on infinite lists.
|
|
|
|
cycle :: [a] -> [a]
|
|
cycle [] = error "Prelude.cycle: empty list"
|
|
cycle xs = xs' where xs' = xs ++ xs'
|
|
|
|
|
|
15. zipWith, zip, unzip
|
|
|
|
-- | 'zipWith' generalises 'zip' by zipping with the function given
|
|
-- as the first argument, instead of a tupling function.
|
|
-- For example, @'zipWith' (+)@ is applied to two lists to produce the
|
|
-- list of corresponding sums.
|
|
zipWith :: (a->b->c) -> [a]->[b]->[c]
|
|
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
|
|
zipWith _ _ _ = []
|
|
|
|
|
|
-- | 'zip' takes two lists and returns a list of corresponding pairs.
|
|
-- If one input list is short, excess elements of the longer list are
|
|
-- discarded.
|
|
zip :: [a] -> [b] -> [(a,b)]
|
|
zip (a:as) (b:bs) = (a,b) : zip as bs
|
|
zip _ _ = []
|
|
|
|
|
|
-- | 'unzip' transforms a list of pairs into a list of first components
|
|
-- and a list of second components.
|
|
unzip :: [(a,b)] -> ([a],[b])
|
|
{-# INLINE unzip #-}
|
|
unzip = foldr (\(a,b) ~(as,bs) -> (a:as,b:bs)) ([],[])
|
|
|
|
|
|
|