2016-05-04 11 views
4

Ich habe meine eigene Art:Bool Klasse - wie Num?

data MyType = ... 

Nun würde ich Wert dieser Art in if verwenden möchten. Ist es möglich, es zu implementieren? Natürlich in diesem Moment bekomme ich Fehler:

Couldn't match expected type ‘Bool’ with actual type ‘MyType’ 

Antwort

7

Die Standard-Semantik von if/then/else spezifisch sind Bool. Mit GHC ist es möglich, die Standardsemantik mit der Erweiterung RebindableSyntax zu ändern. Zitat aus der Dokumentation:

...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.

Dies ist meine technische Antwort auf die Frage, wie gefragt.

Aber meine meinungliche Antwort ist, dass Sie das nicht tun sollten. Schreiben Sie stattdessen ein Prädikat vom Typ MyType -> Bool; Verwenden Sie dann if predicate myValue then ... else .... Dieser explizite Weg ist meiner Meinung nach klarer und idiomatisch; und als Nebennutzen ist auch flexibler, weil Sie viele verschiedene Prädikate dieses Typs haben können, anstatt jeden einzelnen zu einem besonderen Status zu erheben.

+0

Vielen Dank! –

1

Sie konnte es wahrscheinlich mit -XRebindableSyntax (obwohl Sie Daniel Wagner hören sollte und dies nicht tun):

{-# 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 

Dann in GHCi:

> :l decidable.hs 
> :set -XRebindableSyntax 
> P.putStrLn (if A then "it worked!" else "it failed!") 
it worked! 

Auch dies nicht tun ! Gehen Sie einfach mit einer einfachen Funktion, es wird eine Menge Kopfschmerzen auf der ganzen Linie speichern und wird niemanden sonst verwirren, der Ihren Code liest, der nicht merkt, dass Sie die Syntax der Sprache geändert haben.