Caching internals with a partially applied function - haskell

Imagine such a function:
bar :: Foo -> A -> B -> C -> IO ()
That function performs some IO stuff using a Foo and other values. The Foo value has to be passed to bar, and can be retrieved from IO via this:
foo :: X -> IO Foo
Now, A, B, C and X are all plain pure values. I’d rather like such a bar function:
bar :: X -> A -> B -> C -> IO ()
And Foo would be generated in the bar function using the X value. If I do that :
let f = bar myX
f :: A -> B -> C -> IO (). If I call that function several times, the X value remains the same because of partial application, but since it’s an IO effect, it will be generated each time. Is there a native, built-in-ghc way to perform some kind of caching so that the Foo value is generated once – for the generated closure? I guess it’s all boxing-related, but I never figured out how to do that without using dirty IORef, expanding the parameters of bar, which is ugly.

What you are literally asking would break referential transparency, a big "no" in Haskell. So that leaves me with the question, should I show you the unsafeLaunchMissiles kind of method that does (sometimes, if you are lucky and optimizations don't break it) what you literally ask but is highly discouraged, or should I show the clean way that changes the types just a little? Let me try the latter.
If you make your bar have the following type instead:
bar :: X -> IO (A -> B -> C -> IO ())
Then you can use, in a do block:
f <- bar myX
Alternatively, if you think that misses the point of redefining bar to take an X, then instead keep your first type for bar and do
f <- bar =<< foo myX

Related

How can I modify the windowSet in XMonad?

I have a function that looks like:
sinkFocus :: StackSet i l a s sd -> Maybe (StackSet i l a s sd)
sinkFocus = (fmap . flip sink) <*> peek
However I would like an X () so that I can use it. For example additionalKeys uses an X ().
The documentation says that X is a IO with some state and reader transformers, so I am under the impression that the StackSet is contained within the state of X. So in theory it should be possible to modify the relevant part of the state. However the state accessible is XState not the StackState I want, so I need to be able to turn my function on StackState to one on XState.
This would be easy enough if I had a function of the type
(StackSet i l a s sd -> StackSet i l a s sd) -> X ()
However after digging around in the documentation I haven't been able to piece together a way to do this yet. Is there a way to take a function on StackSet and make an X () that performs that function?
The X monad has an instance of MonadState
instance MonadState XState X
So we can use modify as
modify :: (XState -> XState) -> X ()
So we need to turn out function to one on XStates. And if we look at the definition
XState
windowset :: !WindowSet
mapped :: !(Set Window)
waitingUnmap :: !(Map Window Int)
dragging :: !(Maybe (Position -> Position -> X (), X ()))
numberlockMask :: !KeyMask
extensibleState :: !(Map String (Either String StateExtension))
we will see WindowSet which is a type alias for a particular StackState. So you can turn a function from StackStates into one on XStates like so:
overWindowSet :: (WindowSet -> WindowSet) -> XState -> XState
overWindowSet f xState = xState { windowset = f (windowset xState) }
This can be combined with modify to make the complete function you would like:
modify . overWindowSet

IO (Maybe Picture) -> Picture

I'm creating a game with Gloss.
I have this function :
block :: IO (Maybe Picture)
block = loadJuicyPNG "block.png"
How do I take this IO (Maybe Picture) and turn it into a Picture?
You need to bind the value. This is done either with the bind function (>>=), or by do-notation:
main :: IO ()
main = do
pic <- block
case pic of
Just p -> ... -- loading succeeded, p is a Picture
Nothing -> ... -- loading failed
It is a Maybe Picture because the loading might fail, and you have to handle that possible failure somehow.
This is basically the same answer as Bartek's, but using a different approach.
Let's say you have a function foo :: Picture -> Picture the transforms a picture in some way. It expects a Picture as an argument, but all you have is block :: IO (Maybe Picture); there may or may not be a picture buried in there, but it's all you have.
To start, let's assume you have some function foo' :: Maybe Picture -> Maybe Picture. It's definition is simple:
foo' :: Maybe Picture -> Maybe Picture
foo' = fmap foo
So simple, in fact, that you never actually write it; wherever you would use foo', you just use fmap foo directly. What this function does, you will recall, is return Nothing if it gets Nothing, and return Just (foo x) if it gets some value Just x.
Now, given that you have foo', how do you apply it to the value buried in the IO type? For that, we'll use the Monad instanced for IO, which provides us with two functions (types here specialized to IO):
return :: a -> IO a
(>>=) :: IO a -> (a -> IO b) -> IO b
In our case, we recognize that both a and b are Maybe Picture. If foo' :: Maybe Picture -> Maybe Picture, then return . foo' :: Maybe Picture -> IO (Maybe Picture). That means we can finally "apply" foo to our picture:
> :t block >>= return . (fmap foo)
block >>= return . (fmap foo) :: IO (Maybe Picture)
But we aren't really applying foo ourselves. What we are really doing is lifting foo into a context where, once block is executed, foo' can be called on whatever block produces.

data type with a default field and that needs a function that works with it

Say, I have a data type
data FooBar a = Foo String Char [a]
| Bar String Int [a]
I need to create values of this type and give empty list as the second field:
Foo "hello" 'a' []
or
Bar "world" 1 []
1) I do this everywhere in my code and I think it would be nice if I could omit the empty list part somehow and have the empty list assigned implicitly. Is this possible? Something similar to default function arguments in other languages.
2) Because of this [] "default" value, I often need to have a partial constructor application that results in a function that takes the first two values:
mkFoo x y = Foo x y []
mkBar x y = Bar x y []
Is there a "better" (more idiomatic, etc) way to do it? to avoid defining new functions?
3) I need a way to add things to the list:
add (Foo u v xs) x = Foo u v (x:xs)
add (Bar u v xs) x = Bar u v (x:xs)
Is this how it is done idiomatically? Just a general purpose function?
As you see I am a beginner, so maybe these questions make little sense. Hope not.
I'll address your questions one by one.
Default arguments do not exist in Haskell. They are simply not worth the added complexity and loss of compositionally. Being a functional language, you do a lot more function manipulation in Haskell, so funkiness like default arguments would be tough to handle.
One thing I didn't realize when I started Haskell is that data constructors are functions just like everything else. In your example,
Foo :: String -> Char -> [a] -> FooBar a
Thus you can write functions for filling in various arguments of other functions, and then those functions will work with Foo or Bar or whatever.
fill1 :: a -> (a -> b) -> b
fill1 a f = f a
--Note that fill1 = flip ($)
fill2 :: b -> (a -> b -> c) -> (a -> c)
--Equivalently, fill2 :: b -> (a -> b -> c) -> a -> c
fill2 b f = \a -> f a b
fill3 :: c -> (a -> b -> c -> d) -> (a -> b -> d)
fill3 c f = \a b -> f a b c
fill3Empty :: (a -> b -> [c] -> d) -> (a -> b -> d)
fill3Empty f = fill3 [] f
--Now, we can write
> fill3Empty Foo x y
Foo x y []
The lens package provides elegant solutions to questions like this. However, you can tell at a glance that this package is enormously complicated. Here is the net result of how you would call the lens package:
_list :: Lens (FooBar a) (FooBar b) [a] [b]
_list = lens getter setter
where getter (Foo _ _ as) = as
getter (Bar _ _ as) = as
setter (Foo s c _) bs = Foo s c bs
setter (Bar s i _) bs = Bar s i bs
Now we can do
> over _list (3:) (Foo "ab" 'c' [2,1])
Foo "ab" 'c' [3,2,1]
Some explanation: the lens function produces a Lens type when given a getter and a setter for some type. Lens s t a b is a type that says "s holds an a and t holds a b. Thus, if you give me a function a -> b, I can give you a function s -> t". That is exactly what over does: you provide it a lens and a function (in our case, (3:) was a function that adds 3 to the front of a List) and it applies the function "where the lens indicates". This is very similar to a functor, however, we have significantly more freedom (in this example, the functor instance would be obligated to change every element of the lists, not operate on the lists themselves).
Note that our new _list lens is very generic: it works equally well over Foo and Bar and the lens package provides many functions other than over for doing magical things.
The idiomatic thing is to take those parameters of a function or constructor that you commonly want to partially apply, and move them toward the beginning:
data FooBar a = Foo [a] String Char
| Bar [a] String Int
foo :: String -> Char -> FooBar a
foo = Foo []
bar :: String -> Int -> FooBar a
bar = Bar []
Similarly, reordering the parameters to add lets you partially apply add to get functions of type FooBar a -> FooBar a, which can be easily composed:
add :: a -> FooBar a -> FooBar a
add x (Foo xs u v) = Foo (x:xs) u v
add123 :: FooBar Int -> FooBar Int
add123 = add 1 . add 2 . add 3
add123 (foo "bar" 42) == Foo [1, 2, 3] "bar" 42
(2) and (3) are perfectly normal and idiomatic ways of doing such things. About (2) in particular, one expression you will occasionally hear is "smart constructor". That just means a function like your mkFoo/mkBar that produces a FooBar a (or a Maybe (FooBar a) etc.) with some extra logic to ensure only reasonable values can be constructed.
Here are some additional tricks that might (or might not!) make sense, depending on what you are trying to do with FooBar.
If you use Foo values and Barvalues in similar ways most of the time (i.e. the difference between having the Char field and the Int one is a minor detail), it makes sense to factor out the similarities and use a single constructor:
data FooBar a = FooBar String FooBarTag [a]
data FooBarTag = Foo Char | Bar Int
Beyond avoiding case analysis when you don't care about the FooBarTag, that allows you to safely use record syntax (records and types with multiple constructors do not mix well).
data FooBar a = FooBar
{ fooBarName :: String
, fooBarTag :: FooBarTag
, fooBarList :: [a]
}
Records allow you to use the fields without having to pattern match the whole thing.
If there are sensible defaults for all fields in a FooBar, you can go one step beyond mkFoo-like constructors and define a default value.
defaultFooBar :: FooBar a
defaultFooBar = FooBar
{ fooBarName = ""
, fooBarTag = Bar 0
, fooBarList = []
}
You don't need records to use a default, but they allow overriding default fields conveniently.
myFooBar = defaultFooBar
{ fooBarTag = Foo 'x'
}
If you ever get tired of typing long names for the defaults over and over, consider the data-default package:
instance Default (FooBar a) where
def = defaultFooBar
myFooBar = def { fooBarTag = Foo 'x' }
Do note that a significant number of people do not like the Default class, and not without reason. Still, for types which are very specific to your application (e.g. configuration settings) Default is perfectly fine IMO.
Finally, updating record fields can be messy. If you end up annoyed by that, you will find lens very useful. Note that it is a big library, and it might be a little overwhelming to a beginner, so take a deep breath beforehand. Here is a small sample:
{-# LANGUAGE TemplateHaskell #-} -- At the top of the file. Needed for makeLenses.
import Control.Lens
-- Note the underscores.
-- If you are going to use lenses, it is sensible not to export the field names.
data FooBar a = FooBar
{ _fooBarName :: String
, _fooBarTag :: FooBarTag
, _fooBarList :: [a]
}
makeLenses ''FooBar -- Defines lenses for the fields automatically.
defaultFooBar :: FooBar a
defaultFooBar = FooBar
{ _fooBarName = ""
, _fooBarTag = Bar 0
, _fooBarList = []
}
-- Using a lens (fooBarTag) to set a field without record syntax.
-- Note the lack of underscores in the name of the lens.
myFooBar = set fooBarTag (Foo 'x') defaultFooBar
-- Using a lens to access a field.
myTag = view fooBarTag myFooBar -- Results in Foo 'x'
-- Using a lens (fooBarList) to modify a field.
add :: a -> FooBar a -> FooBar a
add x fb = over fooBarList (x :) fb
-- set, view and over have operator equivalents, (.~). (^.) and (%~) respectively.
-- Note that (^.) is flipped with respect to view.
Here is a gentle introduction to lens which focuses on aspects I have not demonstrated here, specially in how nicely lenses can be composed.

Is there a way to capture the continuations in a do notation?

Since the following do block:
do
x <- foo
y <- bar
return x + y
is desugared to the following form:
foo >>= (\x -> bar >>= (\y -> return x + y))
aren't \x -> ... and y -> ... actually continuations here?
I was wondering if there is a way to capture the continuations in the definition of bind, but I can't get the types right. I.e:
data Pause a = Pause a | Stop
instance Monad Pause where
return x = Stop
m >>= k = Pause k -- this doesn't work of course
Now I tried muddling around with the types:
data Pause a = Pause a (a -> Pause ???) | Stop
------- k ------
But this doesn't work either. Is there no way to capture these implicit continuations?
Btw, I know about the Cont monad, I'm just experimenting and trying out stuff.
OK I'm not really sure, but let me put a few thoughts. I'm not quite sure what it
ought to mean to capture the continuation. You could, for example, capture the whole
do block in a structure:
{-# LANGUAGE ExistentialQuantification #-}
import Control.Monad
data MonadExp b = Return b | forall a. Bind (MonadExp a) (a -> MonadExp b)
instance Monad MonadExp where
return x = Return x
f >>= g = Bind f g
For example:
block :: MonadExp Int
block = do
x <- return 1
y <- return 2
return $ x + y
instance Show (MonadExp a) where
show (Return _) = "Return _"
show (Bind _ _) = "Bind _ _"
print block
>> Bind _ _
And then evaluate the whole thing:
finish :: MonadExp a -> a
finish (Return x) = x
finish (Bind f g) = finish $ g (finish f)
print $ finish block
>> 3
Or step through it and see the parts
step :: MonadExp a -> MonadExp a
step (Return _) = error "At the end"
step (Bind f g) = g $ finish f
print $ step block
>> Bind _ _
print $ step $ step block
>> Return _
Well, now that I think about it more, that's probably not what you're asking. But
maybe it'll help you think.
Well, I don't know if your lambdas are continuations in the strictest sense of the term, but they also look similar to this concept in my eye.
But note that if they are continuations, then the desugared monadic code is already written in continuation passing style (CPS). The usual notion of a control operator that "captures" a continuation is based on direct-style programs; the "captured" continuation is only implicit in the direct-style program, but the CPS transformation makes it explicit.
Since the desugared monadic code is already in CPS or something like it, well, maybe a way to frame your question is whether monadic code can express some of the control flow tricks that CPS code can. Typically, those tricks boil down to the idea that while under the CPS regime it is conventional for a function to finish by invoking its continuation, a function can choose to replace its continuation with another of its choosing. This replacement continuation can be constructed with a reference to the original continuation, so that it can in turn "restore" that original one if it chooses. So for example, coroutines are implemented as a mutual "replace/restore" cycle.
And looked at in this light, I think your answer is mostly no; CPS requires that in foo >>= bar, foo must be able to choose whether bar will be invoked at all, and foo must be abble to supply a substitute for bar, but (>>=) by itself does not offer a mechanism for foo to do this, and more importantly, (>>=) is in control of the execution flow, not foo. Some specific monads implement parts or all of it (for example, the Maybe monad allows foo to forego execution of bar by producing a Nothing result), but others don't.
Closest I could get is to forego (>>=) and use this instead:
-- | Execute action #foo# with its "continuation" #bar#.
callCC :: Monad m => ((a -> m b) -> m b) -> (a -> m b) -> m b
foo `callCC` bar = foo bar
Here foo can choose whether bar will be used at all. But notice that this callCC is really just ($)!

Haskell confusion with ContT, callCC, when

Continuing quest to make sense of ContT and friends. Please consider the (absurd but illustrative) code below:
v :: IO (Either String [String])
v = return $ Left "Error message"
doit :: IO (Either String ())
doit = (flip runContT return) $ callCC $ \k -> do
x <- liftIO $ v
x2 <- either (k . Left) return x
when True $ k (Left "Error message 2")
-- k (Left "Error message 3")
return $ Right () -- success
This code does not compile. However, if the replace the when with the commented k call below it, it compiles. What's going on?
Alternatively, if I comment out the x2 line, it also compiles. ???
Obviously, this is a distilled version of the original code and so all of the elements serve a purpose. Appreciate explanatory help on what's going on and how to fix it. Thanks.
The problem here has to do with the types of when and either, not anything particular to ContT:
when :: forall (m :: * -> *). (Monad m) => Bool -> m () -> m ()
either :: forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
The second argument needs to be of type m () for some monad m. The when line of your code could thus be amended like so:
when True $ k (Left "Error message 2") >> return ()
to make the code compile. This is probably not what you want to do, but it gives us a hint as to what might be wrong: k's type has been inferred to be something unpalatable to when.
Now for the either signature: notice that the two arguments to either must be functions which produce results of the same type. The type of return here is determined by the type of x, which is in turn fixed by the explicit signature on v. Thus the (k . Left) bit must have the same type; this in turn fixes the type of k at (GHC-determined)
k :: Either String () -> ContT (Either String ()) IO [String]
This is incompatible with when's expectations.
When you comment out the x2 line, however, its effect on the type checker's view of the code is removed, so k is no longer forced into an inconvenient type and is free to assume the type
k :: Either [Char] () -> ContT (Either [Char] ()) IO ()
which is fine in when's book. Thus, the code compiles.
As a final note, I used GHCi's breakpoints facility to obtain the exact types of k under the two scenarios -- I'm nowhere near expert enough to write them out by hand and be in any way assured of their correctness. :-) Use :break ModuleName line-number column-number to try it out.

Resources