How do I reuse an intermediate value in chain of Haskell Either binds? - haskell

I'm sure this has been answered but apparently I don't know what to search for.
I am working on my first non-trivial Haskell program -- a simulation of a card game I enjoy. I have the program working but there is a situation that I am certain can be handled better.
If I have a series of binds which are Either String TypeChangesBasedOnTheFunction.
playerInput <- getLine
case playerInput of
{- CASE STUFF NOT IMPORTANT TO THIS QUESTION -}
_ -> do let handValue = inputHasAllValidChars playerInput >>= makeDeckFromString >>= deckSubset (getCurrentPlayersDeck gameState) >>= whatHandRepresents >>= handBeatsCurrentTopTrick
Very soon after this part of the code runs, I need the value for whatHandRepresents. I can just run the same chain of binds again but I am certain there must be a better way by storing the value when it is determined in the code above.
My question is, is it possible to store this value. If so, how?

You have to thread it all the way back up to where you need it.
repr <- case playerInput of
-- now you have to return something of the appropriate type,
-- say, `Left "didn't get it"`, from these other cases.
_ -> do let repr = ... >>= whatHandRepresents
handValue = repr >>= handBeatsCurrentTopTrick
-- use handValue
return repr
-- now use repr :: Either String HandRepresentationOrWhatever
I sure hope you actually are using handValue within the default case and not trying to assign it for use later on. It will only be in scope within that case; if you want to use it afterward you have to return it also, just like repr (e.g. in a tuple).

Related

Maybe-like monad that gives breadcrumbs when Nothing occurs

I have two record types
data OptionalRecord = OptionalRecord
{ mFoo :: Maybe Foo
, mBar :: Maybe Bar
, mBaz :: Maybe Baz
}
data RequiredRecord = RequiredRecord
{ foo :: Foo
, bar :: Bar
, baz :: Baz
}
I have a function:
optionalToRequired :: OptionalRecord -> Maybe RequiredRecord
optionalToRequired OptionalRecord{..} =
do
foo <- mFoo
bar <- mBar
baz <- mBaz
return RequiredRecord{..}
This funcion works fine, but when it returns Nothing, I don't have any info about which field (or line in the do block) was Nothing.
Does anyone have any suggestions for an alternative that includes more info, like line number, that doesn't require a lot of embellishment?
William's suggestion in the comments is a good one: if you use Either instead of Maybe, then instead of Nothing, your computations can produce information about why they failed. But you do have to provide this information: you can't just get it automatically from the compiler with a line number for the bind. Indeed you can't introduce any information with a bind that doesn't come from the monadic value being binded, because this would break the Monad laws.
A common example of this is "What if I could count how many calls to >>= (or uses of <- in do-notation) there have been?". You can see why that doesn't work in the question Is it possible to create a Monad that count the number of instructions?.
As others have stated, Either a meets the requirements you've mentioned, but there is a very good reason for this: Either a behaves the same as Maybe as a Monad.
It can only hold a single value or no values.
An "error" value (Left foo or Nothing) short-circuits further computations whereas a "success" value (Right bar or Just bar) does not. (This means that you can only use Right as an indication of success and Left as an indication of an error.)
You can pattern-match "error" and "success" values at the end.
There is a large variety of Monad semantics out there, and having the concept of an error message isn't alone sufficient to take the place of Maybe.

In Haskell, if a function returns a "Maybe a" type just so it is safe and total, how is it useful anymore?

So I have to define a safe version of the head function that would not throw an error when [] is passed as the argument. Here it is:
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
But now, is this function still of any use? Because suppose that type "a" is a Int, then you can add two objects of type Int, but you can't add two objects of type "Maybe Int".
As it was mentioned in comments, you can actually add two Maybes. I just wanted to give another point of view on that.
Yes, you can't directly apply (+) to Maybe Ints, but you can upgrade it to another function that is able to do so automatically.
To upgrade unary function (like (+1)) you write fmap (+1) maybeInt or (+1) <$> maybeInt. If (+1) had type Int -> Int, the fmap (+1) expression has type Maybe Int -> Maybe Int.
Upgrading bin-or-more-ary functions is a bit more complex syntax-wise: (+) <$> maybeInt <*> maybeInt or liftA2 (+) maybeInt maybeInt. Again, here we promote (+) :: Int -> Int -> Int to liftA2 (+) :: Maybe Int -> Maybe Int -> Maybe Int.
Handling Maybes this way allows you to build up a computation that works with Maybes out of pure functions and defer checking for Nothing. Or even avoid that if you eventually plug it into another function that takes Maybe as argument.
Of course, you can use fmap and liftAs on any Applicative, not just Maybe.
"Just" is one such function. Here's how you can use its result (for the ghci REPL):
import Data.Foldable (sequenceA_)
let writeLn = putStrLn . show
let supposedlyUnusable = writeLn <$> Just 0
sequenceA_ supposedlyUnusable
which prints 1 or we can continue to try the other interesting example - using the Nothing case
let supposedlyUnusable = writeLn <$> Nothing
sequenceA_ supposedlyUnusable
which doesn't print anything.
That's a complete program which works even for other instances of Traversable or Foldable where you couldn't do a case analysis on the Maybe value. <$> is the key that lets you apply a function to whatever's contained in the Maybe or any Functor and if you have two Maybes (or two of the same Applicative) you can use the pattern fn <$> applicative_a <*> applicative_b which is like fn a b but where a and b are wrapped up things like Maybe values.
So that leaves a couple of remaining ways to use a Maybe that I can think of, all of which use case analysis:
let {fn (Just n) = Just $ 1 + n; fn Nothing = Nothing}
fn v
-- but that was just a messy way of writing (1+) <$> v
...
let fn v = case v of {Just n -> Just $ 1 + n; Nothing -> Nothing}
-- and that's the same program with a different syntax
...
import Data.Maybe (fromMaybe)
fromMaybe someDefault v
-- and that extracted the `value` from `v` if we had `Just value` or else gave us `someDefault`
...
let {fn (Just n) = writeLn n; fn Nothing = putStrLn "No answer"}
-- this one extracts an action but also provides an action when there's nothing
-- it can be done using <$> and fromMaybe instead, but beginners tend to
-- find it easier because of the tutorials that resulted from the history
-- of the base library's development
let fn v = fromMaybe (putStrLn "No answer") (writeLn <$> v)
oooh, oooh! This one's neato:
import Control.Applicative
let v = Just 0 -- or Nothing, if you want
let errorcase = pure $ putStrLn "No answer"
let successcase = writeLn <$> v
sequenceA_ $ successcase <|> errorcase
-- that uses Alternative in which Maybe tries to give an answer preferring the earliest if it can
of course we also have the classic:
maybe (putStrLn "No answer") writeLn v
Safety comes with a cost. The cost is normally extra code, for avoiding error situations. Haskell has given us the way to avoid this at the compile time rather than at run time.
Let me explain with examples from other languages. Though I won't name any language, but it would be apparent which languages I am talking about. Please be sure that all languages are great in their ways, so do not take this as I am finding fault in other language.
In some languages you have pointers and the way you will do safeHead is to return either int pointer or null pointer. You will have to de-reference pointer to get the value and when you de-reference null pointer you will get error. To avoid this, extra code will be needed to check for null pointer, and do something when it is null.
In some dynamic languages, you have variables assigned to null. So in above example your variable could be type int or it could be null. And what will happen if you add null to int? Most probably undefined situation. Again special handling needs to be done for the null case.
In Haskell too you will have to do the same, you will have to guard the null situation with extra code. So what's the difference? The difference in Haskell is doing it at the compile time and not at the run time.* i.e. the moment you have this kind of code along with your definition of safeHead, p = safeHead xs + safeHead ys, the code will give error at the compile time. You will have to do something more for addition if type Maybe Int. You can write your function for adding two or multiple Maybe Ints or create newype for Maybe Int and overload + or do something as mentioned in other answers.
But whatever you do, you do it before unit testing. Definitely much before it goes on production. And earlier the error is caught lesser is the cost. That's where the advantage of type safe Haskell comes in handy.
* There could be mechanism in other languages to handle this at compile time.

Monads return empty type: return ()

type InterpreterMonad = ErrorT String ((StateT (Stack EnvEval)) IO)
argsToContext :: [DefArg] -> [CallArg] -> InterpreterMonad ()
argsToContext xs ys = argsToContext' xs ys Map.empty where
argsToContext' ((ArgForDefinition t name):xs) ((ArgForCall e):ys) m = get >>= \contextStack -> (argsToContext' xs ys (Map.insert name e m ))
argsToContext' [] [] m = get >>= \contextStack -> (put (push contextStack m)) >>= \_ -> return ()
data DefArg =
ArgForDefinition Type VarName
data CallArg =
ArgForCall Evaluable
Hi,
I've got a problem with understanding above piece of Haskell code
Especially, I cannot understand how does it return () and why it is placed here.
Please explain.
return in Haskell does not mean what it means in imperative languages like C or Java. In fact its really the wrong name, but we are stuck with it for historical reasons. Better names would be "pure" or "wrap", meaning that it takes a pure value and wraps it up into the monadic context.
The () type is known as "unit". Its not actually empty because it has one value, also called () (hence the name). However it is sort-of empty because you use it when you don't want to convey any information: there is only one value, so it needs zero bits to represent it. (There is a "Void" type available for when you really don't want it to have any values).
So return () means that this monadic action wraps a unit up in the monadic context. In effect its a no-op: do nothing and return no information.
In this case its being used in the case where the arguments are two empty lists. argsToContext' has the job of pairing up the DefArg list with the CallArg list. The first definition takes the head of each list, does its thing with them, and then calls itself with the tails of each list. When the tails are both empty it calls the second version which puts the resulting context on top of the context stack. If the two lists are of different length then it will throw an exception because neither pattern matches. If its your code then you ought to put in a defensive case, partly to help you debug, partly to show that you actually thought about the case, and partly to stop the compiler nagging you about it.
The 'context' in this case is the interpreter's variables, which are held in the Map. Hence the only effect of argsToContext' is to add these pairs to the context and then return a 'Unit' value. The InterpreterMonad is the monadic type, and the return value has the type InterpreterMonad (), meaning that no information is returned, it just has side effects within the monadic context.
In fact I don't think you need the return () here because put already has type m () for whatever monad you are in. So just delete the >>= \_ -> return () and I think it will work fine.

Accessing vector element by index using lens

I'm looking for a way to reference an element of a vector using lens library...
Let me try to explain what I'm trying to achieve using a simplified example of my code.
I'm working in this monad transformer stack (where StateT is the focus, everything else is not important)
newtype MyType a = MyType (StateT MyState (ExceptT String IO) a)
MyState has a lot of fields but one of those is a vector of clients which is a data type I defined:
data MyState = MyState { ...
, _clients :: V.Vector ClientT
}
Whenever I need to access one of my clients I tend to do it like this:
import Control.Lens (use)
c <- use clients
let neededClient = c V.! someIndex
... -- calculate something, update client if needed
clients %= (V.// [(someIndex, updatedClient)])
Now, here is what I'm looking for: I would like my function to receive a "reference" to the client I'm interested in and use it (retrieve it from State, update it if needed).
In order to clear up what I mean here is a snippet (that won't compile even in pseudo code):
...
myFunction (clients.ix 0)
...
myFunction clientLens = do
c <- use clientLens -- I would like to access a client in the vector
... -- calculate stuff
clientLens .= updatedClient
Basically, I would like to pass to myFunction something from Lens library (I don't know what I'm passing here... Lens? Traversal? Getting? some other thingy?) which will allow me to point at particular element in the vector which is kept in my StateT. Is it at all possible? Currently, when using "clients.ix 0" I get an error that my ClientT is not an instance of Monoid.
It is a very dumbed down version of what I have. In order to answer the question "why I need it this way" requires a lot more explanation. I'm interested if it is possible to pass this "reference" which will point to some element in my vector which is kept in State.
clients.ix 0 is a traversal. In particular, traversals are setters, so setting and modifying should work fine:
clients.ix 0 .= updatedClient
Your problem is with use. Because a traversal doesn't necessarily contain exactly one value, when you use a traversal (or use some other getter function on it), it combines all the values assuming they are of a Monoid type.
In particular,
use (clients.ix n)
would want to return mempty if n is out of bounds.
Instead, you can use the preuse function, which discards all but the first target of a traversal (or more generally, a fold), and wraps it in a Maybe. E.g.
Just c <- preuse (clients.ix n)
Note this will give a pattern match error if n is out of bounds, since preuse returns Nothing then.

Converting IO Int to Int

I've created a combobox from converting a xmlWidget to a comboBox with the function castTocomboBox and now I want to get the text or the index of the active item. The problem is that if I use the comboBoxGetActive function it returns an IO Int result and I need to know how can I obtain the Int value. I tried to read about monads so I could understand what one could do in a situation like this but I don't seem to understand. I appreciate all the help I can get. I should probably mention that I use Glade and gtk2hs.
As a general rule you write something like this:
do
x <- somethingThatReturnsIO
somethingElseThatReturnsIO $ pureFunction x
There is no way to get the "Int" out of an "IO Int", except to do something else in the IO Monad.
In monad terms, the above code desugars into
somethingThatReturnsIO >>= (\x -> somethingElseThatReturnsIO $ pureFunction x)
The ">>=" operator (pronounced "bind") does the magic of converting the "IO Int" into an "Int", but it refuses to give that Int straight to you. It will only pass that value into another function as an argument, and that function must return another value in "IO". Meditate on the type of bind for the IO monad for a few minutes, and you may be enlightened:
>>= :: IO a -> (a -> IO b) -> IO b
The first argument is your initial "IO Int" value that "comboBoxGetActive" is returning. The second is a function that takes the Int value and turns it into some other IO value. Thus you can process the Int, but the results of doing so never escape from the IO monad.
(Of course there is the infamous "unsafePerformIO", but at your level of knowledge you may be certain that if you use it then you are doing it wrong.)
(Actually the desugaring is rather more complicated to allow for failed pattern matches. But you can pretend what I wrote is true)
Well, there is unsafePerformIO: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/System-IO-Unsafe.html#v:unsafePerformIO
(If you want to know how to find this method: Go to http://www.haskell.org/hoogle and search for the signature you need, here IO a -> a)
That said, you probably heard of "What happens in IO stays in IO". And there are very good reasons for this (just read the documentation of unsafePerformIO). So you very likely have a design problem, but in order to get help from experienced Haskellers (I'm certainly not), you need to describe your problem more detailed.
To understand what those types are –step by step–, first look up what Maybe and List are:
data Maybe a = Nothing | Just a
data [a] = [] | a : [a]
(Maybe a) is a different type than (a), like (Maybe Int) differs from (Int).
Example values of the type (Maybe Int) are
Just 5 and Nothing.
A List of (a)s can be written as ([ ] a) and as ([a]). Example values of ([Int]) are [1,7,42] and [ ].
Now, an (IO a) is a different thing than (a), too: It is an Input/Output-computation that calculates a value of type (a). In other words: it is a script or program, which has to be executed to generate a value of type (a).
An Example of (IO String) is getLine, which reads a line of text from standard-input.
Now, the type of comboBoxGetActive is:
comboBoxGetActive :: ComboBoxClass self => self -> IO Int
That means, that comboBoxGetActive is a function (->) that maps from any type that has an instance of the type-class ComboBoxClass (primitive type-classes are somehow similar to java-interfaces) to an (IO Int). Each time, this function (->) is evaluated with the same input value of this type (self) (whatever that type is), it results in the same value: It is always the same value of type (IO Int), that means that it is always the same script. But when you execute that same script at different times, it could produce different values of type (Int).
The main function of your program has the type (IO ()), that means that the compiler and the runtime system evaluate the equations that you program in this functional language to the value of main, which will be executed as soon as you start the program.

Resources