Haskell 里的概念
Haskell 建立在范畴学(Category theory)之上,里面有繁复又抽象的概念,学习曲线很陡。
- 学习抽象概念的方法,从具体到抽象 byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/
- wiki.haskell.org/A_brief_introduction_to_Haskell
- caiorss.github.io/Functional-Programming/haskell/Functional_Programming_Concepts.html
- 图解 functors, applicatives 和 monads
- ndrgrnd.net/posts/haskellOneSentence.html
- monad
- recursive function
- monad transformer
- lift
- optics(lens and prisms)
- currying
- map
- predicate
- filter
- pure functions
- lambda
- lazy evaluation: YouTube video (bnRNiE_OVWA)
- fold
- morphism
- category
- functors
- types
- type classes
- algebraic data types
- parametric polymorphism
- monoid
- free monads
目前我已经知道了上面这个列表里的打勾的这些概念,下面是我对剩余概念的理解记录。
Type class
In computer science, a type class is a type system construct that supports parametric polymorphism. This is achieved by adding constraints to type variables in parametrically polymorphic types. Such a constraint typically involves a type class T and a type variable a, and means that a can only be instantiated to
a
type whose members support the overloaded operations associated withT
.
类型(type)类(class)接受一个类型参数,生成一个新的类型,这个新的类型支持这个类型类所定义的一组方法。可以类比于面向对象编程(OOP)里的类(class),不过传输的参数变成了一个类型。
Functor, fmap
, Lift
如图所示,这是Functor
的定义。它是一个Type class
,这个类型类定义了fmap
方法。此方法接受两个参数,分别是函数a -> b
和 Functor
f a
,这里a
和b
都是类型,f
也是类型,不过是它的类型属于类型类(type class)
,同时a
作为Functor
的参数生成f a
这个Functor``实例(instance of type class)
,它是一个类型(type)
。
调用 fmap
时,它把具有a
类型的值从f a
里取出来,传到函数a -> b
里,再把具有类型b
的值放入Functor``f
里,返回fb
。
fmap
执行的操作就叫做lift
。同时,fmap
也写作<$>
。
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
-- 类型类的实例
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
另外,Functor
遵循两个定律:
fmap id = id -- 1st functor law: id是单元运算符
fmap (g . f) = fmap g . fmap f -- 2nd functor law: 组合函数交换律
Applicative
如图所示,Applicative
更进一步,它的第一个参数也变成了一个 Functor
,不过盒子里面放的东西是函数 a -> b
。如果在上一小节里的第一个参数是个空Functor
,Applicative
也知道如何处理。
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
instance Applicative Maybe where
pure = Just
(Just f) <*> (Just x) = Just (f x)
_ <*> _ = Nothing
方法<*>
也称作liftA
。
同样,Applicative
也有它应该满足的定律:
pure id <*> v = v -- Identity
pure f <*> pure x = pure (f x) -- Homomorphism
u <*> pure y = pure ($ y) <*> u -- Interchange
pure (.) <*> u <*> v <*> w = u <*> (v <*> w) -- Composition
Monads
Monads apply a function that returns a wrapped value to a wrapped value. Monads have a function
>>=
(pronounced “bind”) to do this.
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
instance Monad Maybe where
return :: a -> Maybe a
return x = Just x
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
m >>= g = case m of
Nothing -> Nothing
Just x -> g x
方法>>=
又称作liftM
。
它需要遵从的定律是:
m >>= return = m -- right unit
return x >>= f = f x -- left unit
(m >>= f) >>= g = m >>= (\x -> f x >>= g) -- associativity
总的来说,Monad
可以将三个函数串联在一起,输入输出都是Monad
。
Applicative
是Monad
的超类(superclass)。所以,Monad
即是Applicative
也是Functor
。
Category
范畴论(category theory)
里的范畴
,是对象(objects)、映射(morphisms)和映射的组态(configure)的集合(collection)。
Morphisms
映射,在不同数学领域有不同表现。比如集合论里的函数,线性代数里的线性变换,群论里的群同态,拓扑逻辑里的连续函数。
在范畴论里,是同种数据结构间的映射,有时也叫箭(Arrows)。
Optics
Optics 翻译是光学,允许在数据类型里存取数据。另外翻到一篇天书 Categories of Optics。
Algebraic data type
代数数据类型,一种结合了其他类型组合成的组合数据类型。
Two common classes of algebraic types are product types (i.e., tuples and records) and sum types (i.e., tagged or disjoint unions, coproduct types or variant types).
The values of a product type typically contain several values, called fields. All values of that type have the same combination of field types. The set of all possible values of a product type is the set-theoretic product, i.e., the Cartesian product, of the sets of all possible values of its field types.
The values of a sum type are typically grouped into several classes, called variants. A value of a variant type is usually created with a quasi-functional entity called a constructor. Each variant has its own constructor, which takes a specified number of arguments with specified types. The set of all possible values of a sum type is the set-theoretic sum, i.e., the disjoint union, of the sets of all possible values of its variants. Enumerated types are a special case of sum types in which the constructors take no arguments, as exactly one value is defined for each constructor.
Values of algebraic types are analyzed with pattern matching, which identifies a value by its constructor or field names and extracts the data it contains.
代数数据类型结合模式匹配,可以提取出数据结构里的值。
Polymorphism
多态,指为不同数据类型的实体提供统一的接口。简单来说,所谓多态意指相同的消息给予不同的对象会引发不同的动作。
Parametric Polymorphism
参数多态,跟平常听到的泛型比较相关。Go语言里用接口实现参数多态。
Parametric Polymorphism is a way to define types or functions that are generic over other types.
The genericity can be expressed by using type variables for the parameter type, and by a mechanism to explicitly or implicitly replace the type variables with concrete types when necessary.
Product
对象的外积,可以类比二维空间中的面积,图中是X1 x X2
是外积的结果,pi1
和 pi2
是外积在坐标轴X1
和X2
上的投影。
Y
可能不等于X1 x X2
,因为坐标轴可能不是正交的。
Monoid
monoid,孤立点是一个拥有以下两个的单形范畴(monoidal category,二元外积值域是本范畴的范畴)里的一个对象:
- 对象外积的是自身
- 单元映射的是自身