如何学习Haskell

发布于 2020-03-21 12:21:46

Haskell 里的概念

Haskell 建立在范畴学(Category theory)之上,里面有繁复又抽象的概念,学习曲线很陡。

目前我已经知道了上面这个列表里的打勾的这些概念,下面是我对剩余概念的理解记录。

Type class

From Type class - Wikipedia

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 with T.

类型(type)类(class)接受一个类型参数,生成一个新的类型,这个新的类型支持这个类型类所定义的一组方法。可以类比于面向对象编程(OOP)里的类(class),不过传输的参数变成了一个类型。

Functor, fmap, Lift

如图所示,这是Functor的定义。它是一个Type class,这个类型类定义了fmap方法。此方法接受两个参数,分别是函数a -> bFunctor f a,这里ab都是类型,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。如果在上一小节里的第一个参数是个空FunctorApplicative 也知道如何处理。

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

ApplicativeMonad的超类(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是外积的结果,pi1pi2 是外积在坐标轴X1X2上的投影。

Y可能不等于X1 x X2,因为坐标轴可能不是正交的。

Monoid

monoid,孤立点是一个拥有以下两个的单形范畴(monoidal category,二元外积值域是本范畴的范畴)里的一个对象:

  • 对象外积的是自身
  • 单元映射的是自身

Free monads

What are free monads

参考链接

comments powered by Disqus