在介面 ( class)中包含“智能建構式”方法是一種優良傳統:
class Collection c a where
empty :: c a
singleton :: a -> c a
-- etc
將它們作為模式同義詞提供會很好:
{-# LANGUAGE PatternSynonyms #-}
instance Ord a => Collection [] a where
empty = []
singleton x = [x]
pattern PEmpty = []
pattern PSingleton x = [x]
但是您不能將 PatSyns 放在類中。我有一些作業,但它似乎有很多丑陋的代碼。任何人都可以建議清理它的方法嗎?(下面列出了具體的丑陋。)
{-# LANGUAGE ViewPatterns #-}
pattern PEmpty :: (Eq (c a), Collection c a) => c a
pattern PEmpty <- ((==) empty -> True) where
PEmpty = empty
pattern PSingleton :: (Ord a, Collection c a) => a -> c a
pattern PSingleton x <- (isSingleton -> Just x) where
PSingleton x = singleton x
-- needs an extra method in the class:
isSingleton :: c a -> Maybe a
-- instance ...
isSingleton [x] = Just x
isSingleton _ = Nothing
- 令人討厭的是,這些必須是明確的雙向模式;特別是因為 'under
where' 行與實體多載如此直接可比。 - 對于
empty模式,我必須引入一個明確的(==)測驗和支持Eq約束——以實作簡單的模式匹配。(我想我可以呼叫一個isEmpty方法。) - 對于該
singleton模式,我避免了顯式(==)測驗,但需要在類中的方法上加倍。 - 我真的不喜歡
ViewPatterns;我希望 PatSyns 可以提供一些方法來避免它們。
uj5u.com熱心網友回復:
如果您可以將模式同義詞放在類實體中,那么您的解決方案將更加簡單:您根本不需要emptyorsingleton在類中,因為它們可以用PEmptyand來定義PSingleton。唉,如您所知,這在當前的 GHC 中是不可能的。
正如,你只能定義在類的功能和型別,并沒有獲得建構式(如[]與:在串列中的例子),你需要兩個函式來定義圖案同義詞:一個從型別中提取資料,一個用于嵌入它。
至于你關于丑陋的具體觀點,有些是不可避免的,但對于其他人來說,可能有一個稍微干凈的方法。
令人討厭的是,這些必須是明確的雙向模式;特別是因為 'under
where' 行與實體多載如此直接可比。
唉,這是不可避免的。如果無法訪問類中的建構式,則需要顯式使用雙向模式。
對于
empty模式,我必須引入一個明確的(==)測驗和支持Eq約束——以實作簡單的模式匹配。(我想我可以呼叫一個isEmpty方法。)
我個人認為您的代碼使用isEmpty方法會更干凈。對于它的價值,您可以根據需要使用默認簽名,例如:
class Collection c a where
...
isEmpty :: c a -> Bool
default isEmpty :: Eq (c a) => c a -> Bool
isEmpty = (==) empty
對于該
singleton模式,我避免了顯式(==)測驗,但需要在類中的方法上加倍。
你這樣說就像你有選擇一樣,但我認為你不能只用相等測驗來撰寫這種模式。您正在嘗試從未知集合中提取值,如果沒有您的班級的支持,我看不出您如何做到這一點。一種extractSingleton方法似乎很合理,就像headMay :: [a] -> Maybe a(的安全版本head)很合理一樣。
我真的不喜歡
ViewPatterns;我希望 PatSyns 可以提供一些方法來避免它們。
這是另一個“唉”的時刻。很抱歉您不喜歡ViewPatterns,但它們幾乎是撰寫雙向模式同義詞的唯一方法。
您沒有提到的最重要的事情是圍繞完整模式匹配的問題。您可能會發現,即使您擁有這些新模式,它們也會拋出關于非詳盡模式匹配的各種警告。您可能想要定義一個更通用的類似“cons”的模式來破壞您的集合。然后,您可以COMPLETE為PEmptyand添加一個編譯指示PCons。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/407296.html
標籤:
