我有一個像這樣的型別類實體:
instance {-# OVERLAPPABLE #-} (TypeError ( 'Text "Some error")) => SomeClass x where
someMethod = undefined
此實體存在于其他(有效)實體的末尾。這個想法是讓編譯器在用戶撰寫不符合這些有效實體的型別時拋出型別錯誤。TypeError例如,約束實作了這一點,但這也迫使我用 填充方法undefined,這感覺就像是 hack。
有沒有辦法避免這種情況?還是做得更好?
這是具有這種模式的真實代碼。
uj5u.com熱心網友回復:
我能做到的最好的就是這個。本質上,我定義了一個TypeErr代表標準約束和提供所需見證TypeError的附加約束的型別族。總是無法解決為約束,但無論如何都會首先觸發型別錯誤。ImpossibleImpossible
{-# LANGUAGE DataKinds, UndecidableInstances, TypeFamilies #-}
import GHC.TypeLits (
ErrorMessage (Text),
TypeError,
)
class Impossible where
impossible :: a
type family TypeErr t where
TypeErr t = (TypeError t, Impossible)
-- Dummy example
class SomeClass x where
someMethod :: x -> Maybe x
instance {-# OVERLAPPABLE #-} (TypeErr ( 'Text "Some error"))
=> SomeClass x where
someMethod = impossible
main :: IO ()
main = print (someMethod True)
{-
<source>:19:15: error:
* Some error
* In the first argument of `print', namely `(someMethod True)'
In the expression: print (someMethod True)
In an equation for `main': main = print (someMethod True)
-}
uj5u.com熱心網友回復:
我們在包中有這個Disallowed類。trivial-constraint它提供了nope偽方法,這是一種undefined只能在不可能的情況下使用的版本(并且可以通過“使用” unboxed來證明這一點,這是您無法使用 standard 做的undefined)。
instance {-# OVERLAPPABLE #-} (Disallowed "fallback for `SomeClass`")
=> SomeClass x where
someMethod = nope
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/497526.html
