data Result t
= Ok t
fmap _ (Err msg
) = Err msg
instance Applicative Result where
pure = Ok
Ok f <*> Ok x = Ok (f x)
Ok f <*> Err msg = Err msg
Err msg <*> _ = Err msg
instance Monad Result
where (Ok v) >>= k = k v
(Err msg) >>= k = Err msg
data Item = Item {
getId Nothing = Err "No ID provided"
getItem
:: Int -> Result Item
| id `
rem`
2 == 0 = Ok
( Item
id Nothing
)
getName
:: Item
-> Result
StringgetName
(Item
id Nothing
) = Err
("Item has no name, ID = " ++ show id)getName (Item _ (Just name)) = Ok name
doSomethingClever
id name
= show id ++ " => " ++ name
{-
tryToDoSomethingClever :: Maybe Int -> Result String
tryToDoSomethingClever idParam = do
id <- getId idParam
item <- getItem id
name <- getName item
return (doSomethingClever id name)
tryToDoSomethingClever :: Maybe Int -> Result String
tryToDoSomethingClever idParam =
getId idParam >>= (\id ->
getItem id >>= (\item ->
getName item >>= (\name ->
return (doSomethingClever id name))))
-}
tryToDoSomethingClever idParam =
case getId idParam of
Err msg -> Err msg
Ok
id -> case getItem
id of Err msg -> Err msg
Ok item -> case getName item of
Err msg -> Err msg
Ok name
-> Ok
(doSomethingClever
id name
)
demoInputs = [Nothing, Just 1, Just 2, Just 3]
main
= mapM_ (print . tryToDoSomethingClever
) demoInputs
ZGF0YSBSZXN1bHQgdAogICAgPSBPayB0CiAgICB8IEVyciBTdHJpbmcKICAgIGRlcml2aW5nIChTaG93LCBFcSkKCmluc3RhbmNlIEZ1bmN0b3IgUmVzdWx0IHdoZXJlCiAgICBmbWFwIGYgKE9rICB4KSAgID0gT2sgKGYgeCkKICAgIGZtYXAgXyAoRXJyIG1zZykgPSBFcnIgbXNnCgppbnN0YW5jZSBBcHBsaWNhdGl2ZSBSZXN1bHQgd2hlcmUKICAgIHB1cmUgPSBPawogICAgT2sgIGYgICA8Kj4gT2sgIHggICA9IE9rIChmIHgpCiAgICBPayAgZiAgIDwqPiBFcnIgbXNnID0gRXJyIG1zZwogICAgRXJyIG1zZyA8Kj4gXyAgICAgICA9IEVyciBtc2cKCmluc3RhbmNlIE1vbmFkIFJlc3VsdCB3aGVyZQogICAgKE9rIHYpICAgID4+PSBrID0gayB2CiAgICAoRXJyIG1zZykgPj49IGsgPSBFcnIgbXNnCiAgICByZXR1cm4gdiA9IE9rIHYKICAgIGZhaWwgbXNnID0gRXJyIG1zZwoKZGF0YSBJdGVtID0gSXRlbSB7CiAgICBpZCAgICA6OiBJbnQsCiAgICBuYW1lICA6OiBNYXliZSBTdHJpbmcKICAgIH0gZGVyaXZpbmcgKFNob3csIEVxKQoKZ2V0SWQgOjogTWF5YmUgSW50IC0+IFJlc3VsdCBJbnQKZ2V0SWQgIE5vdGhpbmcgID0gRXJyICJObyBJRCBwcm92aWRlZCIKZ2V0SWQgKEp1c3QgaWQpID0gT2sgaWQKCmdldEl0ZW0gOjogSW50IC0+IFJlc3VsdCBJdGVtCmdldEl0ZW0gaWQKICAgIHwgaWQgYHJlbWAgMiA9PSAwICA9ICBPayAgKCBJdGVtIGlkICBOb3RoaW5nKQogICAgfCBpZCBgcmVtYCAzID09IDAgID0gIE9rICAoIEl0ZW0gaWQgKEp1c3QgKCJpdGVtLSIgKysgc2hvdyBpZCkpKQogICAgfCBvdGhlcndpc2UgICAgICAgID0gIEVyciAoIkl0ZW0gbm90IGZvdW5kLCBJRCA9ICIgKysgc2hvdyBpZCkKCmdldE5hbWUgOjogSXRlbSAtPiBSZXN1bHQgU3RyaW5nCmdldE5hbWUgKEl0ZW0gaWQgTm90aGluZyAgICkgPSBFcnIgKCJJdGVtIGhhcyBubyBuYW1lLCBJRCA9ICIgKysgc2hvdyBpZCkKZ2V0TmFtZSAoSXRlbSBfIChKdXN0IG5hbWUpKSA9IE9rIG5hbWUKCmRvU29tZXRoaW5nQ2xldmVyIDo6IEludCAtPiBTdHJpbmcgLT4gU3RyaW5nCmRvU29tZXRoaW5nQ2xldmVyIGlkIG5hbWUgPSBzaG93IGlkICsrICIgPT4gIiArKyBuYW1lCgp7LQoKdHJ5VG9Eb1NvbWV0aGluZ0NsZXZlciA6OiBNYXliZSBJbnQgLT4gUmVzdWx0IFN0cmluZwp0cnlUb0RvU29tZXRoaW5nQ2xldmVyIGlkUGFyYW0gPSBkbwoJaWQgICA8LSBnZXRJZCBpZFBhcmFtCglpdGVtIDwtIGdldEl0ZW0gaWQKCW5hbWUgPC0gZ2V0TmFtZSBpdGVtCglyZXR1cm4gKGRvU29tZXRoaW5nQ2xldmVyIGlkIG5hbWUpCgp0cnlUb0RvU29tZXRoaW5nQ2xldmVyIDo6IE1heWJlIEludCAtPiBSZXN1bHQgU3RyaW5nCnRyeVRvRG9Tb21ldGhpbmdDbGV2ZXIgaWRQYXJhbSA9CiAgICBnZXRJZCBpZFBhcmFtID4+PSAoXGlkIC0+CiAgICAgICAgZ2V0SXRlbSBpZCA+Pj0gKFxpdGVtIC0+CiAgICAgICAgICAgIGdldE5hbWUgaXRlbSA+Pj0gKFxuYW1lIC0+CiAgICAgICAgICAgICAgICByZXR1cm4gKGRvU29tZXRoaW5nQ2xldmVyIGlkIG5hbWUpKSkpCgotfQoKdHJ5VG9Eb1NvbWV0aGluZ0NsZXZlciA6OiBNYXliZSBJbnQgLT4gUmVzdWx0IFN0cmluZwp0cnlUb0RvU29tZXRoaW5nQ2xldmVyIGlkUGFyYW0gPQogICAgY2FzZSBnZXRJZCBpZFBhcmFtIG9mCiAgICAgICAgRXJyIG1zZyAtPiBFcnIgbXNnCiAgICAgICAgT2sgIGlkICAtPiBjYXNlIGdldEl0ZW0gaWQgb2YKICAgICAgICAgICAgRXJyIG1zZyAgLT4gRXJyIG1zZwogICAgICAgICAgICBPayAgaXRlbSAtPiBjYXNlIGdldE5hbWUgaXRlbSBvZgogICAgICAgICAgICAgICAgRXJyIG1zZyAgLT4gRXJyIG1zZwogICAgICAgICAgICAgICAgT2sgIG5hbWUgLT4gT2sgKGRvU29tZXRoaW5nQ2xldmVyIGlkIG5hbWUpCgpkZW1vSW5wdXRzID0gW05vdGhpbmcsIEp1c3QgMSwgSnVzdCAyLCBKdXN0IDNdCgptYWluID0gbWFwTV8gKHByaW50IC4gdHJ5VG9Eb1NvbWV0aGluZ0NsZXZlcikgZGVtb0lucHV0cwo=