點燈坊

失くすものさえない今が強くなるチャンスよ

FP 之 Type Signature Notation

Sam Xiao's Avatar 2020-04-13

無論學習 Ramda、Crocks 或 Sanctuary,會發現其文件有一種有別於 TypeScript 的 Type 表示法,稱為 Hindley-Milner Type System,這種表示法用於 Haskell,為 FP 廣泛使用的 Type 描述方式。

Version

macOS Catalina 10.15.4

Member of

x :: Number

:: 代表 is a member of,前後都會有 space, 左側為 variable 名稱,右側為 type。

Type Constructor

Array Number

Number 與 Array 都是 type constructor,第一個字母以大寫表示。

其中 Array Number 表示 array 的 element 都是 Number,也就是 [1, 2, 3]

Array (Array Number)

Array (Array Number) 表示 nested array,也就是 [[1,2], [3,4], [5,6]]

Type Variable

a

a, b, c 以小寫表示任意 type。

Array a

Array element 可為任意 type。

Maybe a

任意 type 包在 Maybe 內。

Function Type Constructor

f :: () -> Number

-> 代表 function,左側為 input argument,右側為 return。

() 表示沒有 input。

f :: Number -> Number

Input 為 Number,return 為 Number。

f :: Number -> Number -> Number

若要表示 curried function,只要將 => 換成 -> 即可

Method Type Constructor

Maybe a ~> (a -> b) -> Maybe b

~> 代表掛在 object 下的 method。

Input 為 a -> b,return 為 Maybe a,且為掛在 Maybe a 的 method。

Typeclass Constraint

map :: Functor f => (a -> b) -> f a -> f b

=> 代表 typeclass constraint,左側描述 typeclass,右側為實際應用。

ab 雖然可為任意 type,但必須 constraint 在 Functor 下的任意 type。

Example

fantasy-land/traverse :: Applicative f, Traversable t => t a ~> (TypeRep f, a -> f b) -> f (t b)

fantasy-land/traverse:function / method name

Applicative f, Traversable t:typeclass constraint

t a:method target type,也就是必須是在 Traversable object 下的 method

(TypeRep f, a -> f b):argument type

f (t b):return type

Conclusion

  • Hindley-Milner type system 乍看之下很恐怖,但卻遠比 TypeScript 表示法有效率,很巧妙的將複雜的 FP 精準描述,這也難怪雖然 FP language 與 library 滿天飛,但卻統一使用 Hindley-Milner 表示法

Reference

Jan-Vidar Tandberg Bakke, Type Signatures - Functional Programming for JavaScript Developers
Fantasy Land Specification, Type Signature Notation
Sanctuary, Types