無論學習 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,右側為實際應用。
a
與 b
雖然可為任意 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