4

Ich habe ein Stück Code, wo innerhalb einer Liste Monade, eine Funktion angewendet wird. Funktion möglicherweise möglicherweise nicht erschöpfenden Mustervergleich für seine Argumente. Wenn die Funktion angewendet wird, könnte ich daher "Non-exhaustive pattern matching" Fehler erhalten. Ich möchte diesen Fehler in einen monadischen Fehler umwandeln (in diesem Fall eine leere Liste). Mit anderen Worten, ich möchte ein ähnliches Verhalten wie bei Some Pattern Here <- some value innerhalb eines do Blocks erhalten.Sichere Anwendung in Haskell

Frage: Gibt es eine effiziente Art und Weise eine Funktion Anwendung sicher zu machen? Mit effizient meine ich etwas, das analog dazu wäre, die angewandte Funktion erschöpfend zusammenzuführen und explizit zu versagen.

+0

Die Frage ist nicht klar. Da Sie in der Liste Monade sind, warum passen Sie nicht einfach Muster innerhalb des Do-Konstrukts an oder verwenden Sie andernfalls ein explizites Case-Konstrukt. Es ist besser, einen Beispielcode zu veröffentlichen. – is7s

Antwort

3

Eine Option wäre, spoon zu verwenden, um die Funktion von einer, die Ausnahmen auslöst, in eine zu konvertieren, die Maybe a Werte zurückgibt. Dann sollte es einfach sein, Nothing zu [] zu konvertieren.

+4

Ich bin nicht sicher, ob Spoon aktiv beworben werden sollte, siehe diesen Thread http://www.reddit.com/r/haskell/comments/acasn/tired_of_functions_that_could_live_in_maybe_but/ –

+0

Ich werde wahrscheinlich nicht riskieren, es zu verwenden. Jedenfalls glaube ich, dass dies der nächste ist, den ich erreichen kann, um was ich gebeten habe. – julkiewicz

+2

Ich denke, Löffel ist in Ordnung. Ja, es bricht die theoretischen Eigenschaften und Zeug, aber der Zweck der Bibliothek ist es, mit beschissenem Code zu arbeiten (der nicht so definiert wurde, dass er mit den besagten theoretischen Eigenschaften irgendwie gut spielt). Wenn die Alternative ist, von Grund auf neu zu implementieren (oder in diesem Fall ... den Code des Benutzers zu analysieren und zu korrigieren - blech!), Ist Löffler eine großartige Alternative. – luqui

2

Hum, vielleicht mit einem Haken? Sie sollten jedoch in den IO Monade arbeiten:

import Prelude hiding (catch) 
import Control.Monad (MonadPlus, mzero) 
import Control.Exception (catch, SomeException) 

data B = T | F 
    deriving (Show) 

f :: B -> B 
f T = F 

justCatch :: (MonadPlus m) => a -> IO (m a) 
justCatch x = catch (x `seq` (return . return) x) handler 
    where 
    handler :: (MonadPlus m) => SomeException -> IO (m a) 
    handler _ = return mzero 

ich über mögliche Probleme mit dieser Lösung nicht sicher bin. Auf den ersten Blick scheint es zu funktionieren, aber ich möchte auch einige Meinungen von sachkundigen Haskellers lesen. Ich würde nicht verwenden diese Lösung sicher in meinem Code: ein Fehler sollte als solcher behandelt werden, ohne es zu verstecken.

*Main> justCatch $ f T :: IO [B] 
[F] 
*Main> justCatch $ f F :: IO [B] 
[] 
*Main> justCatch $ f F :: IO (Maybe B) 
Nothing 
*Main> justCatch $ f T :: IO (Maybe B) 
Just F 
*Main> f T 
F 
*Main> f F 
*** Exception: except.hs:8:1-7: Non-exhaustive patterns in function Main.f 
+0

'IO' Monade ist keine Option. Ich versuche, meinen Code so rein wie möglich zu halten. – julkiewicz

+2

Nach meinem besten Wissen können Sie 'catch' nur verwenden, um Ausnahmen wie diese zu behandeln (was Sie zwingt, in IO zu arbeiten). Wenn Sie keinen von Daniel vorgeschlagenen Löffel (der unsichere Operationen verwendet) verwenden möchten, haben Sie vielleicht keine anderen Möglichkeiten. –

+0

Okay, eine negative Antwort ist immer noch eine Antwort. Vielen Dank. – julkiewicz

Verwandte Themen