我正在嘗試擴展(或試圖找出是否有可能擴展)帶有類型簽名的函數,該類型簽名已經達到我的知識範圍,因爲我是庫使用哪些暴露相當多態的類型和API,更多的多態。rankntypes:非法多態或限定類型
我使用的是persistent
和hsqml
,這兩個庫在時刻都有漂亮的毛茸茸的類型,至少對我而言。
我需要將persistent
實體包裝爲hsqml
「代理」對象纔會暴露給QML
(基本上是javascript)。 爲此,我讓自己成爲幫手,叫做getStandardClassMembers
。您可以使用它,像這樣:
instance DefaultClass (Entity Project) where
classMembers = getStandardClassMembers
[
("name", projectName),
("hasCustomIcon", text . not . BS.null . projectIcon),
("hasDev", projectHasDev), -- TODO bool as string, ugly..
("hasUat", projectHasUat),
("hasStaging", projectHasStage),
("hasProd", projectHasProd)
]
[]
的getStandardClassMembers
定義是there。它使用我指定的成員定義了一個javascript對象,並調用我爲實現JS對象的成員而提供的haskell函數。
這很不錯,但有一個'但'。該對中第二個位置的功能必須返回Text
。在這裏你看到,除了第一個功能外,我應該返回一個Bool
。因此,理想情況下,我會讓getStandardClassMembers
的類型簽名採用更多形式的類型,以便不要求第二個函數必須返回Text
。我再一次不知道這是否可能,但我決定試一試。
因此,我將RankNTypes
添加到已經很大的該文件的語言擴展名列表中(由於我選擇的庫很強大,我認爲這很好)。
我改變:
getStandardClassMembers :: (Marshal tr, ToBackendKey SqlBackend record, Typeable record,
MarshalMode tr ICanReturnTo() ~ Yes) =>
[(String, record -> tr)] -> [(String, ObjRef (Entity record) -> Maybe Int)]
-> [Member (GetObjType (ObjRef (Entity record)))]
要:
getStandardClassMembers :: (Marshal tr, ToBackendKey SqlBackend record, Typeable record,
MarshalMode tr ICanReturnTo() ~ Yes) =>
[(String, forall tr. record -> tr)] -> [(String, ObjRef (Entity record) -> Maybe Int)]
-> [Member (GetObjType (ObjRef (Entity record)))]
(所以我加了forall tr.
) ,我得到:
Illegal polymorphic or qualified type: forall tr. record -> tr
Perhaps you intended to use ImpredicativeTypes
現在我知道足夠多的這些事情要知道啓用ImpredicativeTypes
不是一個好主意。另外,如果我啓用它,它也不起作用。
是我想要達到的目標嗎?還是應該讓它休息一下,並且感謝所有那些已經非常雜亂的類型簽名和語言擴展集合?
編輯可能是正確的解決方法是忘記我的幫手,並回到基本使用hsqml
基本API。但除此之外,我仍然好奇這是否可行。
感謝小費如何格式化代碼,我會用「迴歸基本」審查(共同我提到的方法)。但是我沒有完全得到的是,列表中的類型是否真的不同? 'forall'正是試圖統一類型。所有人都喜歡'福爾。記錄 - > a'或某種形狀。也許在返回類型上使用'forall'更麻煩?我仍然不明白爲什麼'RankNTypes'方法不能削減它。 –
啊我現在看到它。這就是你所說的「存在類型可以與封裝一起工作」。就是這樣。所以這是不可行的,除了一個包裝,如在https://wiki.haskell.org/Heterogenous_collections#Existential_types-我知道,但不知何故它沒有「連接」。好吧,我今晚會檢查你的解決方案,記住我的想法,但現在看到只是添加'forall'不能削減它。我想爲什麼會出現在研究論文中,所以就是這樣。 –
@EmmanuelTouzery我不確定在沒有包裝的情況下做存在類型是「真的不可能的」,就像「當包裝使它更簡單時不值得費心去實現」一樣。在[https://wiki.haskell.org/Existential_type](https://wiki.haskell.org/Existential_type)上有一個[Haskell方言]的鏈接(http://www.cs.uu.nl/groups /ST/Projects/ehc/ehc-book.pdf)試圖以不同的方式做到這一點。 –