DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

Notes of Learn You a Haskell for Great Good


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
#!/bin/bash
mkdir Geometry
cat << EOF > Geometry/Sphere.hs
module Geometry.Sphere
( volume
, area
) where

volume :: Float -> Float
volume radius = (4.0 / 3.0) * pi * (radius ^ 3)

area :: Float -> Float
area radius = 4 * pi * (radius ^ 2)
EOF

cat << EOF > app.hs
import Geometry.Sphere
main = print $ volume 3
EOF

runghc app.hs

The result should be "113.097336".

Making Our Own Types and Typeclasses

Value constructor is also called "data constructor".

Ref:

Constructor

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]。



Published

Oct 1, 2015

Last Updated

Oct 1, 2015

Category

Tech

Tags

  • haskell 11
  • tutorial 2

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor