[英]How handling a list of polymorphic variants?
讓兩種變體類型:
type typeA =
| A1
| A2
;;
type typeB =
| B1 of typeA
| B2 of typeA
;;
和類型檢查功能:
let isA1 = function A1 -> true | _ -> false;;
let isA2 = function A2 -> true | _ -> false;;
let isB1 = function B1 e -> true | _ -> false;;
let isB2 = function B2 e -> true | _ -> false;;
我想創建一個列表來檢查A或B類型的元素
因為他們是不同類型,我需要多態變體,我得到:
type filterA =
{
handleA : typeA -> bool;
};;
type filterB =
{
handleB : typeB -> bool;
};;
type filterslist = [`FilterA of filterA | `FilterB of filterB] list ;;
let filters1 = [`FilterA { handleA = isA1 }; `FilterB { handleB = isB1 }] ;;
所以現在我想迭代filters1來檢查我試過的參數的類型:
let exec_filters filters event = List.iter (fun fil -> match fil with `FilterA -> fil.handleA event; ()| `FilterB -> fil.handleB event; () ) filters;;
但不贊賞:
Error: This expression has type [< `FilterA | `FilterB ]
but an expression was expected of type filterA
我怎么處理這個?
你正在使用類似於Scheme或instanceOf的“類型檢查謂詞”這一事實表明你的代碼可能存在一些問題。 OCaml是一種靜態類型語言,你不應該:
迭代filters1以檢查我嘗試過的參數的類型
你為什么做這個? 如果您嘗試處理多種類型,那么執行此操作的方法是使用多態。 多態變體可能對此有所幫助,但我仍然不相信你的代碼不只是以一種奇怪的方式編寫。
我認為您的代碼應如下所示:
let exec_filters filters event =
List.iter
(fun fil -> match fil with
| `FilterA fA -> fA.handleA event; ()
| `FilterB fB -> fB.handleB event; () )
filters;;
編輯:但是,這不會進行類型檢查,因為event
不能有類型typeA
和typeB
...
為什么不把你的最初變種( typeA
和typeB
)多態?
你想做什么?
當你說
match fil with
`FilterA -> ...
你似乎期望這會改變fil
的類型,但這不是它的工作原理。 類型為filterA
的表達式出現在模式中。 你想要更像這樣的東西:
match fil with
`FilterA { handleA = h } -> h event
如果您要使用List.iter
來執行它們,我不確定我是否看到讓處理程序返回bool
的目的。 這將返回unit
,並且將丟棄bool
值。
編輯
Ptival解釋說,存在更深層次的打字問題。 因此,即使您修復了模式,您仍然需要重新考慮您的計划。 一個可能的做法是使用變體(順便說一下,不一定是多態變體)來跟蹤事件的類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.