2016-05-04 1 views

答えて

7

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 the Prelude versions:

  • Conditionals (e.g. if e1 then e2 else e3) means ifThenElse e1 e2 e3 . However case expressions are unaffected.

これは私の質問に対する技術的な回答です。

しかし、私の意見は、あなたがそれをしてはならないということです。代わりに、タイプMyType -> Boolの述部を記述します。 if predicate myValue then ... else ...を使用してください。この明示的なやり方は私の意見ではより明確で慣用的です。任意の1つを特別な状態に上げるのではなく、そのタイプの多くの異なる述語を持つことができるため、副次的な利点はより柔軟です。

+0

ありがとうございます! –

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! 

を再びこれをしません、 !単純な関数を使うだけで、多くの頭痛を節約できますし、他の人にあなたのコードを読んでもらうことはありません。

関連する問題

 関連する問題