2014-04-18 3 views
5

Ich schaute auf den MonadState source code, ich verstehe nicht, warum diese 3 Funktionen nicht in den Leerlauf kommen? Wie wird das bewertet?bekommen und in MonadState setzen

class Monad m => MonadState s m | m -> s where 
    -- | Return the state from the internals of the monad. 
    get :: m s 
    get = state (\s -> (s, s)) 

    -- | Replace the state inside the monad. 
    put :: s -> m() 
    put s = state (\_ -> ((), s)) 

    -- | Embed a simple state action into the monad. 
    state :: (s -> (a, s)) -> m a 
    state f = do 
     s <- get 
     let ~(a, s') = f s 
     put s' 
     return a 
+0

Aus Interesse, was macht das '~' in der 'let' Anweisung? – rafalio

+2

@radicality Es macht das Muster "unwiderlegbar". Aber es tut in diesem Fall nichts, da Muster in einer Let-Bindung sowieso unwiderlegbar sind. Eine unwiderlegbare Musterübereinstimmung teilt dem Compiler mit, dass Sie bezüglich des übereinstimmenden Konstruktors korrekt sind, so dass es die Destrukturierung verzögern kann, bis der Wert eines seiner Argumente tatsächlich erzwungen wird. Wenn Sie sich bei der Verwendung des Konstruktors geirrt haben, wird zu diesem Zeitpunkt eine Ausnahme ausgelöst, jedoch nicht früher. – Carl

Antwort

6

Die Definitionen von get,put,state in der Klasse Erklärung sind die Standardimplementierungen, die in tatsächlichen Instanzen der Klasse außer Kraft gesetzt werden soll werden. Auf diese Weise wird die Dead-Schleife unterbrochen: Wenn eine Instanz nur state definiert, dann werden get und put durch die Verwendung der Standardimplementierung in der Klasse definiert. Wenn eine Instanz get und put definiert, wird state als Standard festgelegt.

Zum Beispiel der Eq Typklasse könnte definiert wurden wie folgt:

class Eq a where 
    (==) :: a -> a -> Bool 
    x == y = not (x /= y) 
    (/=) :: a -> a -> Bool 
    x /= y = not (x == y) 

instance Eq Bool where 
    True == True = True 
    False == False = True 
    _  == _  = False 
    -- the (/=) operator is automatically derived 
instance Eq() where 
    () /=() = False 
    -- the (==) operator is automatically derived 

Es ist in der Tat gemeinsamen Standardselbstbezogene Implementierungen zu haben, die nach unten zu bewerten, es sei denn, etwas in den Instanzen neu definiert wird.

Verwandte Themen