有人可以解釋我的仿函數。我想簡單的例子。當我們應該使用函數?OCaml - 仿函數 - 如何使用?
4
A
回答
3
仿函數本質上是一種根據其他模塊編寫模塊的方法。
一個非常經典的例子是來自標準庫的Map.Make
仿函數。這個函數讓你可以定義一個具有特定鍵類型的地圖。
下面是一個簡單的和相當啞例如:
module Color = struct
type t = Red | Yellow | Blue | Green | White | Black
let compare a b =
let int_of_color = function
| Red -> 0
| Yellow -> 1
| Blue -> 2
| Green -> 3
| White -> 4
| Black -> 5 in
compare (int_of_color a) (int_of_color b)
end
module ColorMap = Map.Make(Color)
加載這在ocaml
示出了所產生的模塊的簽名:
module Color :
sig
type t = Red | Yellow | Blue | Green | White | Black
val compare : t -> t -> int
end
module ColorMap :
sig
type key = Color.t
type 'a t = 'a Map.Make(Color).t
val empty : 'a t
val is_empty : 'a t -> bool
val mem : key -> 'a t -> bool
val add : key -> 'a -> 'a t -> 'a t
val singleton : key -> 'a -> 'a t
val remove : key -> 'a t -> 'a t
val merge :
(key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t
val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val for_all : (key -> 'a -> bool) -> 'a t -> bool
val exists : (key -> 'a -> bool) -> 'a t -> bool
val filter : (key -> 'a -> bool) -> 'a t -> 'a t
val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t
val cardinal : 'a t -> int
val bindings : 'a t -> (key * 'a) list
val min_binding : 'a t -> key * 'a
val max_binding : 'a t -> key * 'a
val choose : 'a t -> key * 'a
val split : key -> 'a t -> 'a t * 'a option * 'a t
val find : key -> 'a t -> 'a
val map : ('a -> 'b) -> 'a t -> 'b t
val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
end
簡單module ColorMap = Map.Make(Color)
創造一個實現地圖,其中一個模塊鑰匙是顏色。它現在可以調用ColorMap.singleton Color.Red 1
並獲得地圖上紅色的數字1
注意的是,使用Map.Make
工作是因爲通過模塊(Color
)滿足Map.Make
函子的要求。文檔說函子的類型是module Make: functor (Ord : OrderedType) -> S with type key = Ord.t
。 : OrderedType
意味着輸入模塊(Color
)必須與OrderedType
模塊簽名保持一致(我敢肯定還有一個更正式的術語)。
爲了與OrderedType
保持一致,輸入模塊必須具有類型t
以及帶簽名t -> t -> int
的功能compare
。換句話說,必須有一種方法來比較t
類型的值。如果您查看ocaml
報告的類型,這正是Color
提供的類型。
何時使用仿函數是一個非常困難的問題,因爲經常有幾種可能的設計,每個都有自己的權衡。但是大多數情況下,當圖書館提供它們作爲推薦的做事方式時,你會使用仿函數。
相關問題
- 1. Haskell中的OCaml仿函數(參數化模塊)
- 2. Priority_queue仿函數使用C++
- 3. HOWTO使用仿函數
- 4. OCaml:樹函數
- 5. OCaml的仿函數取多態性變異型
- 6. Ocaml樹函數
- 7. OCaml使用Async寫入超時函數
- 8. 在OCaml中使用長度函數
- 9. 在OCaml中使用Unix函數源
- 10. OCaml解析函數
- 11. ocaml的函數調用List.fold_left
- 12. 爲什麼在使用函數引用時使用仿函數
- 13. 如何編寫使OCaml中的幾何級數遞歸函數?
- 14. 如何綁定多個參數仿函數使用luabind
- 15. 如何將Ocaml類型與函數映射一起使用?
- 16. 如何使用let in(在ocaml中)編寫遞歸函數
- 17. OCaml遞歸函數
- 18. OCaml檢查函數
- 19. 如何使用應用仿函數來結合Scalaz驗證
- 20. 的函數參數,ocaml的
- 21. lambda函數VS仿函數
- 22. 如何在OCaml中使用List.map
- 23. 參數仿函數
- 24. 如何使用仿函數的工廠模式?
- 25. 瞭解如何在Prolog中使用仿函數
- 26. 如何使用從仿函數與升壓::線程返回值
- 27. 如何「調整」仿函數與map/multimap一起使用?
- 28. 如何實現使用仿函數和運算符()
- 29. 包括仿函數應用
- 30. 應用仿函數分析
您可以在[ocaml.org上的教程](http://ocaml.org/learn/tutorials/modules.html)和[真實世界OCaml的第9章](https://realworldocaml.org/v1 /en/html/functors.html)。 –
簡單地說,仿函數就像Java中的'interface'。 –
@JacksonTale,呃,沒有。與Java接口最接近的是模塊類型,即使這些類型也有很大不同。與函數最接近的是一個泛型類。 –