closestPoint :: Point -> [Point] -> Point closestPoint target = minimumBy (compare `on` distance target)
function
1 2 3
add :: Num a => a -> a -> a -- 类型签名,可以省略 add x y = x + y x = add 11-- 1 `add` 1
curry
1
foo = add 1-- Num a=> a -> a
顺序
1 2 3 4 5
f a b c -- 这个函数等同于 (((f a) b) c) ($) :: (a -> b) -> a -> b (.) :: (b -> c) -> (a -> b) -> a -> c length (takeWhile (<1000) (scanl1 (+) (map sqrt [1..]))) + 1-- 等价于 (+1) $ length $ takeWhile (<1000) $ scanl1 (+) $ map sqrt [1..]
条件判断
1 2 3 4 5 6
safedive :: a -> a -> Maybe a safedive x y = if notzero y thenMaybe (x / y) elseNothing whereMaybe a = Nothing | Just a --真实任意(反c)谓词 safediv x y --pipe | y /= 0 = Just (div x y) | otherwise = Nothing
recursion
1 2 3
factorial :: Integer -> Integer factorial0 = 1 factorial n = n * factorial (n - 1)
classFunctor f where fmap :: (a -> b) -> f a -> f b (<$>) = fmap -- 构造器f天然是范畴中对象间的态射,fmap是范畴中态射的态射 -- <$> is unique, f is confirmed by a & f a instanceFunctorMaybewhere fmap f Nothing = Nothing fmap f (Just a) = Just (f a)
这里的Applicative实际上是幺半群(monoid)
1 2 3 4
f <$> == pure f <*> -- 蕴含pure id <*> == id pure (.) <*> u <*> v <*> w == u <*> (v <*> w) pure f <*> pure x == pure (f x)
1 2 3 4 5 6 7 8 9
class (Functorf) => Applicative f where pure :: a -> f a -- 这里的a可以是函数等,注入、提升 (<*>) :: f (a -> b) -> f a -> f b instanceApplicativeMaybewhere pure = Just Nothing <*> _ = Nothing (Just f) <*> = f <$> Just (+3) <*> Just9-- Just 12
Monad单子:不可拆分, 组成其他对象 半:存在Monad没有把值拿出来的操作
Monad 是一个自函子范畴上的幺半群(对象)
1 2 3
(return x) >>= f == f x m >>= return == m (m >>= f) >>= g == m >>= (\x -> f x >>= g)
1 2 3 4 5 6 7 8 9
classMonad m where return :: a -> m a -- 与pure对应 (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b x >> y = x >>= \_ -> y instanceMonadMaybewhere return x = Just x Nothing >>= f = Nothing Just x >>= f = f x
语法糖do
1 2 3 4 5 6 7 8 9 10 11
safeDiv a b >>= (\x -> safeDiv c x >>= (\y -> safeDiv d y >>= (\z -> safeDiv e z)))
val = do x <- safeDiv a b y <- safeDiv c x z <- safeDiv d y safeDiv e z
内部状态, 如Maybe
1
Just4 >>= tentime --Just 40
外部状态, IO隔绝副作用, 不可能消除
1
IO :: world -> world -> () --()Unit
运算符
单参数函数:<$>(或 fmap)。
多参数函数:liftA2 或链式 <$> 和 <*>。
顺序执行且需传递结果:>>=(Monad)。
顺序执行但忽略结果:*> 或 >>。
错误处理/回退:<|>(Alternative)。
组合 Monadic 函数:>=> 或 <=<。
尾递归优化
重用当前栈帧
1 2 3 4 5 6
def factorialTailRec (n : Nat) : Nat := let rec aux (n : Nat) (acc : Nat) : Nat := match n with | 0 => acc | n + 1 => aux n (acc * (n + 1)) aux n 1
环境
ghci:命令行界面 :+命令 ? help t type l load r reload i info e edit q quit 多行;隔开或:{ :}
.hs
Hoogle查找函数
例子(函数外延性): 传统类型论中,需要假设:
coq
Axiom fun_ext : ∀ (f g : A → B), (∀ x, f x = g x) → f = g.