は、私は自分のタイプを持っています。それを実装することは可能ですか?もちろん、この時点で、私はエラーを取得:BoolクラスのようなNum?私は<code>if</code>で、このタイプの値を使用したい、今すぐ</p> <pre><code>data MyType = ... </code></pre> <p>:
Couldn't match expected type ‘Bool’ with actual type ‘MyType’
は、私は自分のタイプを持っています。それを実装することは可能ですか?もちろん、この時点で、私はエラーを取得:BoolクラスのようなNum?私は<code>if</code>で、このタイプの値を使用したい、今すぐ</p> <pre><code>data MyType = ... </code></pre> <p>:
Couldn't match expected type ‘Bool’ with actual type ‘MyType’
if
/then
/else
の標準セマンティクスはBool
に固有のものです。 GHCでは、標準のセマンティクスをRebindableSyntax
拡張子を使って変更することができます。ドキュメントからの引用:
...the
-XRebindableSyntax
flag causes the following pieces of built-in syntax to refer to whatever is in scope, not thePrelude
versions:
- Conditionals (e.g.
if e1 then e2 else e3
) meansifThenElse e1 e2 e3
. Howevercase
expressions are unaffected.
これは私の質問に対する技術的な回答です。
しかし、私の意見は、あなたがそれをしてはならないということです。代わりに、タイプMyType -> Bool
の述部を記述します。 if predicate myValue then ... else ...
を使用してください。この明示的なやり方は私の意見ではより明確で慣用的です。任意の1つを特別な状態に上げるのではなく、そのタイプの多くの異なる述語を持つことができるため、副次的な利点はより柔軟です。
-XRebindableSyntax
でそれを行うことができ
:GHCiの中に続いて
{-# LANGUAGE RebindableSyntax #-}
module Test where
import qualified Prelude as P
class Decidable b where
toBool :: b -> P.Bool
instance Decidable P.Bool where
toBool = P.id
ifThenElse :: Decidable b => b -> a -> a -> a
ifThenElse b ifTrue ifFalse = case toBool b of
P.True -> ifTrue
P.False -> ifFalse
data Test = A | B deriving (P.Eq, P.Show)
instance Decidable Test where
toBool A = P.True
toBool B = P.False
:
> :l decidable.hs
> :set -XRebindableSyntax
> P.putStrLn (if A then "it worked!" else "it failed!")
it worked!
を再びこれをしません、 !単純な関数を使うだけで、多くの頭痛を節約できますし、他の人にあなたのコードを読んでもらうことはありません。
ありがとうございます! –