Haskell 学习笔记 4

应用函子

  class Functor f => Applicative f where
      pure :: a -> f a   -- minimum context
      (<*>) :: f (a -> b) -> f a -> f b
      pure id <*> v = v  -- identity
      pure (.) <*> u <*> v <*> w = u <*> (v <*> w) -- compostition
      pure f <*> pure x = pure (f x)  -- homomorphism
      u <*> pure y = pure ($ y) <*> u -- interchange

,

, : add minimum context

.

自然升格

  
  <$> :: (a -> b) -> f a -> f b
  f <$> x = fmap f x  -- (= (pure f) <*> x)
  <$ :: a -> f a -> f b
  <$ = fmap . const  -- a <$ x = fmap (const a) x, x $> a
  
  *> :: Applicative f => f a -> f b -> f b
  x *> y = (id <$ x) <*> y = (\_ -> id) <$> x <*> y -- y <* x
  {-
  f a = c -> a
  x *> y = y
  -}
  -- example
  replicate <$> Just 1 *> Just (+1) <*> Just 1234
  -- > 
  
  -- listAx

List、Reader 应用函子

  f a = [a]
  f a = c -> a
  f2 <*> f1 = \x -> f2 x $ f1 x
  -- const id <*> f1 == f1
  
  

反例

f a = Const c a

半群与应用函子

Const 应用函子

Const a 在半群意义下是应用函子.

  
  -- Const a
  instance Monoid a => Applicative (Const a) where
      pure _ = Const mempty
      (Const x) <*> (Const y) = (Const x <> y)

选择应用函子

  -- Monoid a => [a]
  mempty = []
  mappend = ++
  
  -- Monoid a => Maybe a
  empty = Nothing
  Nothing <> x = x <> Nothing = x
  Just x <> Just y = Just (x <> y)
  
  -- Alternative
  class Applicative f => Alternative f where
      empty :: f a
      <|> :: f a -> f a -> f a
      
  instance Alternative [] where
   ...
   instance Alternative Maybe where
   ...

拉链应用函子

  newtype Ziplist = ZipList (getZipList :: [a])
  instance Applicative ZipList where
      pure x = ZipList (repeat x)
      ZipList fs <*> ZipList xs = ZipWith (zipWith ($) fs xs)

Haskell 学习笔记3

类型类

  Eq -- typeclass
  class Eq a where -- declaration of Eq
      (==) :: a -> a -> Bool
      (/=) :: a -> a -> Bool
  
  instance Person where
      (==) :: Person -> Person -> Bool
      p == q = getName p == getName q
      
  Show/Read

数字类型类

  
  -- classes related to numbers
  Ord
  Enum
  Bounded
  -- number class
  Fractional <= Num <= (Eq, Show) -- Num a => Fractional a
  Floating <= Integral <= (Real, Enum)
  Real <= (Num, Ord)

注. Haskell 类型约束信息并不会保存到数据中

Haskell 数据 类型 类型类
范畴论 元素 对象/集合 范畴
例子 3 Int Num

类型声明

类型别名、新类型声明

  type List a = [a]
  type Function1D = Double -> Double
  type Function1D a = a -> a
  
  newtype Transform a = Transform a->a

newtype 避免额外的打包解包过程, 右侧包裹的类型必须是上层类型.

惰性求值

概念

  1. 任务盒(thunk): 只是一个表达式,不进行求值

  2. 常态(normal form): 求值后的表达式; 弱常态:部分求值, 所有构造函数创建的数据都是若常态

  3. 底(bottom):

  
  :print  -- lookup the evaluation
  :sprint
  :force
  
  -- 计算到若常态
  seq :: a -> b -> a
  $!
  -- 计算到常态
  deepseq
  $!!
  force :: NFData a => a -> a

透镜组: 构造函数到构造函数的映射

  type Lens b a = Functor f => (a -> f a) -> b -> f b  -- lens

透镜映射

esp. . : setter, :getter

  -- Lens
  data Point = Point {getX:: Double, getY:: Double}
  data Line = Line {getStart:: Point, getEnd:: Point}
  let setX x p = p {getX = x} -- setX x (P _ _) = (P x _) 
  let xlens f p = fmap (\x -> setX x p) $ f (getX p)
  
  --
  xlens f p = fmap setter $ f $ getter p where
      setter :: Double -> Point
      setter x = p {getX=x}
  --
  xlens f p = fmap (setter p) $ f $ getter p
  
  -- over
  over :: Functor f => ((a -> f a) -> b -> f b) -> (a -> a) -> b -> b
  over :: ((a -> Identity a) -> b -> Identity b) -> (a -> a) -> b -> b
  over lens f x = runIdentity $ lifted x
      where
          lifted = lens (Identity . f)
  -- over
  over lens = \f -> runIdentity . (lens (Identity . f)) :: (a -> a) -> b -> b
  -- over
  xlens f p = (setter p) $ f $ getter p
  
  -- set
  set xlens x p == over xlens (const x) p
  
  -- view
  view :: Lens b a -> b -> a
  view lens x = getConst ((lens Const) x) -- view lens = getConst . (lens Const)
  -- view lens == getter
  
  x ^. lens = view lens x
  lens %~ f x = over lens f x
  lens .~ a x = set lens a x

, -constructor, -deconstructor

.

Haskell 学习笔记2

数据类型

模式,有点接近逻辑推理了(类似合一算法)

  
  data Position = Position Double Double
  data Person = Person String Int Bool
  
  older :: Person -> Person -> Bool
  older Person(a1, b1, c1) Person(a2, b2, c2) = b1 > b2
  match Person(a1, b1, c1) Person(a2, b2, c2) = c1 \= c2 && abs(b1-b2)<=2
      
  older p1@Person(a1, b1, c1) p2@Person(a2, b2, c2) = b1 > b2  -- @pattern

记录语法

  data Person = Person {getName:: String, getAge:: Int, getGender:: Bool}
  p = Person {getName='', getAge=0, getGender=True}
  
  -- exercise
  data Person = Person {getName:: String, getAge:: Int, getGender:: Bool}
  
  show_info :: Person -> String
  show_info p = "My name is " ++ (getName p) ++ ". I am " ++ (show (getAge p)) ++ " years old."
  
  main = do
     print (show_info p) where 
     p = Person {getName="William", getAge=30, getGender=True}

列表递归

列表的盒子比喻

列表元素类型统一

  
  data [a] = a: [a] | []
  1:2:[] == [1,2]
  [1,3..7]
  head (x:xs) = x  -- list pattern
  
  repeat :: a -> [a]
  repeat x = x:repeat x

列表操作

  
  map
  filter
  foldl/foldr
  -- foldl f a [b, c] == f(f(a,b),c)
  scanl/scanr

元组,高阶函数

元组

元组元素可以有不同类型

  
  (a,b,c)
  ("Haskell", 1990, True) :: (String, Int, Bool)

高阶函数

(反)Curry化

  zip/unzip
  
  zipWith (+) [1,2] [1,3]
  -- [2,5]
  
  $ -- application
  & -- piple
  f $ x == f x == x & f
  \x -> f x == f   -- dummy function

Haskell 学习笔记 1

Haskell

假设读者都有函数式编程方面的知识。那些与其他语言相通的东西就不写了。

概念

变量、表达式、类型、绑定、作用域

基本语法

只写一些容易遗忘和另类的语法。

注释

  -- comments
  {- comments
  multi-lines
  -}

表达式

  
  3::[2, 4]  -- ==[3,2,4]
  case x of 'a' -> 1
            'b' -> 2
            'c' -> 3
            
  if ... then ... else ...
  
  let x=a in expr
  expr where x=a

类型

  f :: Double -> Double
  n :: Int
  x :: Double
  x :: String/Char/Num...

模块

  module Main where  -- the name of the module
  import Data.List   -- import an exterial module
  
  ... -- expressions, the body of the module
  
  main :: IO()     -- like main function in C and __main__ in python
  main = print(1+2)

注.

  • Haskell 默认导入Prelude模块

  • List 元素类型必须一样

ghci交互

  
  :t x    -- type of x
  :info x  -- information of x
  :l m -- load a module

运算符

  ++ -- concatenate two lists
  [1,2,3]!!2 -- 3
  fst, snd, head/tail, init/last -- get element(s) in a list
  null [] -- is it an empty list?
  take, drop, reverse, and/or, elem/notElem -- operate lists
  /= -- not equal

 

下面是自己的习作

{-
MyMath: maths functions
-}

module MyMath
(
sgn,
hardlim,
hardlims,
sigmoid,
dsigmoid,
dtanh,
spiky,
gauss,
gauss_std,
gauss_std,
same_sign,
quanfact
) where

sgn :: Double -> Double
sgn x | x<0 = -1
| x>0 = 1
| x==0 = 0

hardlim :: Double -> Double
hardlim x | x < 0 = 0
| x == 0 = 0
| x > 0 = 1

hardlims :: Double -> Double
hardlims x | x < 0 = -1
| x == 0 = 0
| x > 0 = 1

sigmoid :: Double -> Double
sigmoid x = 1 / (1+ exp(-x))

dsigmoid :: Double -> Double
dsigmoid x = y * (1-y)
where y = sigmoid x

dtanh :: Double -> Double
dtanh x = (1+y) * (1-y)
where y = tanh(x)

spiky :: Double -> Double -> Double
spiky x p | x == 0 =0
| x /= 0 =abs(x)**(-1 / (2*p))

gauss :: Double -> Double -> Double -> Double
gauss x mu sigma = exp(-(x – mu)**2 / (2 * sigma**2))

gauss_std :: Double -> Double
gauss_std x = gauss x 0 1

same_sign :: Double -> Double -> Bool
same_sign a b = (a<0 && b<0) || (a>0 && b>0) || (a==0 || b==0)

quanfact :: Double -> Int -> Double
— quantum factorial: (q)n
quanfact q 0 = 1
quanfact q n = (quanfact q (n – 1)) * (1 – q ^ n)

dilation :: Double -> (Double -> Double) -> Double -> Double
dilation x f y = x * (f x*y)

trapint :: (Double -> Double) -> Double -> Double -> Int
trapint f a b n| n == 0 = ((f a) + (f b)) / 2 * (b – a)
| let m = (a+b) / 2 in (trapint f a m n-1) + (trapint f m b n-1)

antider :: (Double -> Double) -> Double -> Double
antider f x = trapint f x 0 10

err = (* 2/pi) . antider gauss