Notes for Learn You a Haskell for Great Good.
Modules
The following code snippet demonstrate how to import and use Haskell submodule. Save the following codes into a shell script and run it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
The result should be "113.097336".
Making Our Own Types and Typeclasses
Value constructor is also called "data constructor".
Ref:
Haskell Type vs Data Constructor
Applicative Functors
下面的代码,转换[1,2,3,4]时,可以用map代替fmap,转换Just 4就不行:
Prelude> fmap (replicate 3) [1,2,3,4]
[[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
Prelude> map (replicate 3) [1,2,3,4]
[[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
Prelude> fmap (replicate 3) (Just 4)
Just [4,4,4]
Prelude> map (replicate 3) (Just 4)
<interactive>:45:20:
Couldn't match expected type ‘[a]’ with actual type ‘Maybe Integer’
Relevant bindings include it :: [[a]] (bound at <interactive>:45:1)
In the second argument of ‘map’, namely ‘(Just 4)’
In the expression: map (replicate 3) (Just 4)
map是一个函数,通过一个将a类型变为b类型的函数, 将元素类型为a类型的数组转换为元素类型为b的数组;
Prelude> :t map
map :: (a -> b) -> [a] -> [b]
fmap是一个函数,通过一个将a类型变为b类型的函数, 将一个类型为"f a"的值,变为一个类型为"f b"的值。
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
Maybe是一个实现了(instance)函子(Functor)类型类(class)的类型构造器(type constructor)。
类型构造器类似于Java的泛型,例如“数组” []就是类型构造器,
“元素为整数的数组” [Int]是一个具体类型,这里的整型 Int就充当了数组类型构造器的参数,
用函数做类比,数组是个“类型函数”,参数是具体类型 Int,返回具体类型 [Int]。
Prelude> :k []
[] :: * -> *
这里:k表示取数组的kind值,kind可以理解为是类型构造器的类型。
*表示某个具体类型(而不是类型构造器)。
Just是一个函数,将a类型值转换为Maybe a类型值,
例如Just 4将Int类型值 (4),转换为Maybe Int,
或者更准确地表述为:将Num类型值转为Num a => Maybe a类型。
Prelude> :k Maybe
Maybe :: * -> *
Prelude> :t Just
Just :: a -> Maybe a
Prelude> :t Just 4
Just 4 :: Num a => Maybe a
由于Just 4的类型Maybe Integer不符合map第二个参数类型[a]的要求,所以报错。
Prelude> :t replicate 3
replicate 3 :: a -> [a]
Prelude> :t fmap (replicate 3) (Just 4)
fmap (replicate 3) (Just 4) :: Num a => Maybe [a]
在上面的计算过程中,(replicate 3)是fmap的第一个参数(a -> b),
这里由于(replicate 3)类型是(a -> [a]),所以b就是[a]。
(Just 4)是第二个参数f a,代入Just 4的类型Maybe a,
可知Functor f就是Maybe.
所以最终f b就是Maybe [a]。