-
-
Save missingfaktor/1266912 to your computer and use it in GitHub Desktop.
-- A simple definition without using any fancy functions. | |
haskell>let ifMaybe pred value = if pred value then Just value else Nothing | |
haskell>:t ifMaybe | |
ifMaybe :: (a -> Bool) -> a -> Maybe a | |
haskell>ifMaybe (const True) 2 | |
Just 2 | |
haskell>ifMaybe (const False) 2 | |
Nothing | |
-- Using functions from standard library. | |
haskell>let ifMaybe pred value = mfilter pred $ Just value | |
haskell>:t ifMaybe | |
ifMaybe :: (a -> Bool) -> a -> Maybe a | |
haskell>ifMaybe (const True) 2 | |
Just 2 | |
haskell>ifMaybe (const False) 2 | |
Nothing | |
-- A point-free version that uses section of (.). | |
haskell>let ifMaybe = (. Just) . mfilter | |
haskell>:t ifMaybe | |
ifMaybe :: (a -> Bool) -> a -> Maybe a | |
haskell>ifMaybe (const True) 2 | |
Just 2 | |
haskell>ifMaybe (const False) 2 | |
Nothing | |
-- Same thing written with (<.|) combinator. | |
haskell>let ifMaybe = mfilter <.| Just | |
haskell>:t ifMaybe | |
ifMaybe :: (a -> Bool) -> a -> Maybe a | |
haskell>ifMaybe (const True) 2 | |
Just 2 | |
haskell>ifMaybe (const False) 2 | |
Nothing | |
haskell> |
@igstan: Yes, you are right. |.>
and <.|
, as I defined them, are not duals of each other. Sorry if I unintentionally implied so in my tweets. And thanks for drawing these diagrams. They make things much more clear for me too. :-)
Here's what you get on applying lambdabot's @unpl
command on these two combinators:
[15:16] <rahul> @unpl \f g -> (f .) . g
[15:16] <lambdabot> \ f g d i -> f (g d i)
[15:16] <rahul> @unpl \f g -> (. g) . f
[15:16] <lambdabot> \ f g d i -> f d (g i)
I am now trying to express these computations in terms of arrows. (With pen and paper) :-)
@igstan: Here is how far I managed to reach. :-)
(|*>) :: (b -> c) -> (a -> b1 -> b) -> (a, b1) -> c
f |*> g = f . uncurry g
(<*|) :: (a -> b -> c) -> (b1 -> b) -> (a, b1) -> c
f <*| g = uncurry f . second g
I changed the names of the functions because these require their arguments tupled. Can you help me make them take arguments in regular curried style?
@missingfaktor: you can write them like this, but it's not really an improvement:
(|*>) :: (b -> c) -> (a -> b1 -> b) -> (a -> b1 -> c)
f |*> g = curry (f . uncurry g)
(<*|) :: (a -> b -> c) -> (b1 -> b) -> (a -> b1 -> c)
f <*| g = curry (uncurry f . second g)
With some help of @djinn
and @pl
commands of lambdabot...
Prelude Control.Arrow Control.Applicative> let regular = (. (,)) . (.)
Prelude Control.Arrow Control.Applicative> :t regular
regular :: ((a, b) -> c) -> a -> b -> c
Prelude Control.Arrow Control.Applicative> let f |.> g = regular $ f . uncurry g
Prelude Control.Arrow Control.Applicative> :t (|.>)
(|.>) :: (b1 -> c) -> (a -> b -> b1) -> a -> b -> c
Ok, I see now. So, I don't think
|.>
and<.|
are dual (you didn't say this though). Here's some ASCII art to describe the machinery:What
|.>
does:What
<.|
does:The dual of
<.|
would be:This looks a lot like Arrows, but I'm not sure I can express them in terms of those combinators. http://en.wikibooks.org/wiki/Haskell/Understanding_arrows