So the Maybe data type is defined like this:
data Maybe a = Just a | Nothing
What would you call the data type that's conceptually opposite to Maybe:
data <Type> = Okay | Error String
That is, a type that declares the computation successful or holds some error produced by the computation.
I refute the premise that this type is in a meaningful sense “opposite” to Maybe. I also don't agree that Either should generally be understood as an error-signalling type – that's just quite a natural way of using it, due to the way its monad instance works.
Both Maybe and Either know nothing about errors / failure – they're just implementations of the abstract concept of a sum type (in the case of Maybe a sum with the unit type).
IMO, you should just use Maybe String for this purpose, or if you like it explicit:
type ErrorMsg = String
type PossibleError = Maybe ErrorMsg
I would use Either String (), using the common convention that an Either is used to signal errors with information in the Left and the success value in the Right. If you don't actually have a success value, use the unit type ().
Of course, that still needs to be wrapped in some monad, because in Haskell a pure function without a result is not useful. If the purpose of your function is just to check the validity of some data, then it's not an error to return the error string, and I'd go back to using Maybe.
Your <Type> is equivalent to Either String (), so you could just have
type CanError = Either String ()
isOkay :: CanError -> Bool
isOkay = Data.Either.isRight
isError :: CanError -> Bool
isError = Data.Either.isLeft
getErrorMsg :: CanError -> Maybe String
getErrorMsg (Left msg) = Just msg
getErrorMsg _ = Nothing
You can use Either String as a Monad/Applicative/Functor, but not CanError since it has kind *, not * -> * as required by each of those typeclasses. I would recommend just using Either String as is since you get the extra power of Monad/Applicative/Functor/etc., and when you need the equivalent of CanError just have the return type be Either String () in-line.
Another example for what perhaps is the general idea behind your question, that success is the exceptional case and failure is the normal case, is EitherR as provided in the errors package whose Monad instance is suggestively referred to as the "success" monad. As the name suggests there's no magic here, it's just a newtype with Monad instances swapped around. The interpretation, however, is interesting.
You can program in a world where success falls through while errors are kept around. As the package documentation indicates, this comes in handy when dealing with stacks of exception handlers.
Related
Obviously, the following function is impossible, because it is impossible to unwrap an IO value permanently (ignoring unsafePerformIO or similar):
unwrapIO :: IO String -> String
unwrapIO (IO str) = str
However, similar functions such as the following are possible:
unwrapJust :: Maybe String -> String
unwrapJust (Just str) = str
unwrapJust Nothing = "ignore this plz"
I fully understand the reasoning behind why #2 is possible but #1 is not, but I do not understand how. Can I also make my own types that are not unwrappable?
Just and Nothing are data constructors for the type Maybe a. IO has no data constructors to speak of (in GHC it actually has constructors but they're really implementation details of GHC, and other implementations might define IO differently).
unwrapIO (IO str) = str doesn't make sense in the same way unwrapMaybe (Maybe str) = str doesn't make sense. IO and Maybe are not data constructors, so you cannot pattern-match on them.
It's because the data constructor of IO is not exported. I mean, you can think it's not exported.
You can prevent your own type from being unwrapped by using the same strategy.
module Test (Test, test) where
data Test a = MkTest a
test :: a -> Test a
test = MkTest
You can create a value of Test using test, but you cannot unwrap it using pattern-match because MkTest is not exported.
I believe that while the existing answers are mostly true, there is a deeper reason why IO can not be unwrapped. Conceptually, type IO a = RealWorld -> (a, RealWorld). IO is a function type (in real implementations hidden behind a newtype wrapper or equivalent machinery).
So, how would you go about unwrapping a function? Easy, you just call it!. But how are you going to get an instance of RealWorld? That is the truer primitive: you can not construct a RealWorld, there is only ever one.
The monadic instance of course can just pass RealWorld as a state, kind of like StateT and in the end, the only instance ever constructed is at startup of the program, then it is passed down between the IOs.
Coming back to reality again, this is (again) a lie. You actually can get hold of an instance of RealWorld and you can call an IO a action "ahead of time". There is a function that does exactly what you asked for. It is called System.IO.Unsafe.unsafePerformIO :: IO a -> a though it is in an unsafe package for a reason.
Just curious, seems when declaring a name, we always specify some valid values, like let a = 3. Question is, in imperative languages include c/java there's always a keyword of "null". Does Haskell has similar thing? When could a function object be null?
There is a “null” value that you can use for variables of any type. It's called ⟂ (pronounced bottom). We don't need a keyword to produce bottom values; actually ⟂ is the value of any computation which doesn't terminate. For instance,
bottom = let x = x in x -- or simply `bottom = bottom`
will infinitely loop. It's obviously not a good idea to do this deliberately, however you can use undefined as a “standard bottom value”. It's perhaps the closest thing Haskell has to Java's null keyword.
But you definitely shouldn't/can't use this for most of the applications where Java programmers would grab for null.
Since everything in Haskell is immutable, a value that's undefined will always stay undefined. It's not possible to use this as a “hold on a second, I'll define it later” indication†.
It's not possible to check whether a value is bottom or not. For rather deep theoretical reasons, in fact. So you can't use this for values that may or may not be defined.
And you know what? It's really good that Haskell does't allow this! In Java, you constantly need to be wary that values might be null. In Haskell, if a value is bottom than something is plain broken, but this will never be part of intended behaviour / something you might need to check for. If for some value it's intended that it might not be defined, then you must always make this explicit by wrapping the type in a Maybe. By doing this, you make sure that anybody trying to use the value must first check whether it's there. Not possible to forget this and run into a null-reference exception at runtime!
And because Haskell is so good at handling variant types, checking the contents of a Maybe-wrapped value is really not too cumbersome. You can just do it explicitly with pattern matching,
quun :: Int -> String
quun i = case computationWhichMayFail i of
Just j -> show j
Nothing -> "blearg, failed"
computationWhichMayFail :: Int -> Maybe Int
or you can use the fact that Maybe is a functor. Indeed it is an instance of almost every specific functor class: Functor, Applicative, Alternative, Foldable, Traversable, Monad, MonadPlus. It also lifts semigroups to monoids.
Dᴏɴ'ᴛ Pᴀɴɪᴄ now,
you don't need to know what the heck these things are. But when you've learned what they do, you will be able to write very concise code that automagically handles missing values always in the right way, with zero risk of missing a check.
†Because Haskell is lazy, you generally don't need to defer any calculations to be done later. The compiler will automatically see to it that the computation is done when it's necessary, and no sooner.
There is no null in Haskell. What you want is the Maybe monad.
data Maybe a
= Just a
| Nothing
Nothing refers to classic null and Just contains a value.
You can then pattern match against it:
foo Nothing = Nothing
foo (Just a) = Just (a * 10)
Or with case syntax:
let m = Just 10
in case m of
Just v -> print v
Nothing -> putStrLn "Sorry, there's no value. :("
Or use the supperior functionality provided by the typeclass instances for Functor, Applicative, Alternative, Monad, MonadPlus and Foldable.
This could then look like this:
foo :: Maybe Int -> Maybe Int -> Maybe Int
foo x y = do
a <- x
b <- y
return $ a + b
You can even use the more general signature:
foo :: (Monad m, Num a) => m a -> m a -> m a
Which makes this function work for ANY data type that is capable of the functionality provided by Monad. So you can use foo with (Num a) => Maybe a, (Num a) => [a], (Num a) => Either e a and so on.
Haskell does not have "null". This is a design feature. It completely prevents any possibility of your code crashing due to a null-pointer exception.
If you look at code written in an imperative language, 99% of the code expects stuff to never be null, and will malfunction catastrophically if you give it null. But then 1% of the code does expect nulls, and uses this feature to specify optional arguments or whatever. But you can't easily tell, by looking at the code, which parts are expecting nulls as legal arguments, and which parts aren't. Hopefully it's documented — but don't hold your breath!
In Haskell, there is no null. If that argument is declared as Customer, then there must be an actual, real Customer there. You can't just pass in a null (intentionally or by mistake). So the 99% of the code that is expecting a real Customer will always work.
But what about the other 1%? Well, for that we have Maybe. But it's an explicit thing; you have to explicitly say "this value is optional". And you have to explicitly check when you use it. You cannot "forget" to check; it won't compile.
So yes, there is no "null", but there is Maybe which is kinda similar, but safer.
Not in Haskell (or in many other FP languages). If you have some expression of some type T, its evaluation will give a value of type T, with the following exceptions:
infinite recursion may make the program "loop forever" and failing to return anything
let f n = f (n+1) in f 0
runtime errors can abort the program early, e.g.:
division by zero, square root of negative, and other numerical errors
head [], fromJust Nothing, and other partial functions used on invalid inputs
explicit calls to undefined, error "message", or other exception-throwing primitives
Note that even if the above cases might be regarded as "special" values called "bottoms" (the name comes from domain theory), you can not test against these values at runtime, in general. So, these are not at all the same thing as Java's null. More precisely, you can't write things like
-- assume f :: Int -> Int
if (f 5) is a division-by-zero or infinite recursion
then 12
else 4
Some exceptional values can be caught in the IO monad, but forget about that -- exceptions in Haskell are not idiomatic, and roughly only used for IO errors.
If you want an exceptional value which can be tested at run-time, use the Maybe a type, as #bash0r already suggested. This type is similar to Scala's Option[A] or Java's not-so-much-used Optional<A>.
The value is having both a type T and type Maybe T is to be able to precisely identify which functions always succeed, and which ones can fail. In Haskell the following is frowned upon, for instance:
-- Finds a value in a list. Returns -1 if not present.
findIndex :: Eq a => [a] -> a -> Int
Instead this is preferred:
-- Finds a value in a list. Returns Nothing if not present.
findIndex :: Eq a => [a] -> a -> Maybe Int
The result of the latter is less convenient than the one of the former, since the Int must be unwrapped at every call. This is good, since in this way each user of the function is prevented to simply "ignore" the not-present case, and write buggy code.
I'm reading Learn You a Haskell, and in the monad chapters, it seems to me that () is being treated as a sort of "null" for every type. When I check the type of () in GHCi, I get
>> :t ()
() :: ()
which is an extremely confusing statement. It seems that () is a type all to itself. I'm confused as to how it fits into the language, and how it seems to be able to stand for any type.
tl;dr () does not add a "null" value to every type, hell no; () is a "dull" value in a type of its own: ().
Let me step back from the question a moment and address a common source of confusion. A key thing to absorb when learning Haskell is the distinction between its expression language and its type language. You're probably aware that the two are kept separate. But that allows the same symbol to be used in both, and that is what is going on here. There are simple textual cues to tell you which language you're looking at. You don't need to parse the whole language to detect these cues.
The top level of a Haskell module lives, by default, in the expression language. You define functions by writing equations between expressions. But when you see foo :: bar in the expression language, it means that foo is an expression and bar is its type. So when you read () :: (), you're seeing a statement which relates the () in the expression language with the () in the type language. The two () symbols mean different things, because they are not in the same language. This replication often causes confusion for beginners, until the expression/type language separation installs itself in their subconscious, at which point it becomes helpfully mnemonic.
The keyword data introduces a new datatype declaration, involving a careful mixture of the expression and type languages, as it says first what the new type is, and secondly what its values are.
data TyCon tyvar ... tyvar = ValCon1 type ... type | ... | ValConn type ... type
In such a declaration, type constructor TyCon is being added to the type language and the ValCon value constructors are being added to the expression language (and its pattern sublanguage). In a data declaration, the things which stand in argument places for the ValCons tell you the types given to the arguments when that ValCon is used in expressions. For example,
data Tree a = Leaf | Node (Tree a) a (Tree a)
declares a type constructor Tree for binary tree types storing a elements at nodes, whose values are given by value constructors Leaf and Node. I like to colour type constructors (Tree) blue and value constructors (Leaf, Node) red. There should be no blue in expressions and (unless you're using advanced features) no red in types. The built-in type Bool could be declared,
data Bool = True | False
adding blue Bool to the type language, and red True and False to the expression language. Sadly, my markdown-fu is inadequate to the task of adding the colours to this post, so you'll just have to learn to add the colours in your head.
The "unit" type uses () as a special symbol, but it works as if declared
data () = () -- the left () is blue; the right () is red
meaning that a notionally blue () is a type constructor in the type language, but that a notionally red () is a value constructor in the expression language, and indeed () :: (). [ It is not the only example of such a pun. The types of larger tuples follow the same pattern: pair syntax is as if given by
data (a, b) = (a, b)
adding (,) to both type and expression languages. But I digress.]
So the type (), often pronounced "Unit", is a type containing one value worth speaking of: that value is also written () but in the expression language, and is sometimes pronounced "void". A type with only one value is not very interesting. A value of type () contributes zero bits of information: you already know what it must be. So, while there is nothing special about type () to indicate side effects, it often shows up as the value component in a monadic type. Monadic operations tend to have types which look like
val-in-type-1 -> ... -> val-in-type-n -> effect-monad val-out-type
where the return type is a type application: the (type) function tells you which effects are possible and the (type) argument tells you what sort of value is produced by the operation. For example
put :: s -> State s ()
which is read (because application associates to the left ["as we all did in the sixties", Roger Hindley]) as
put :: s -> (State s) ()
has one value input type s, the effect-monad State s, and the value output type (). When you see () as a value output type, that just means "this operation is used only for its effect; the value delivered is uninteresting". Similarly
putStr :: String -> IO ()
delivers a string to stdout but does not return anything exciting.
The () type is also useful as an element type for container-like structures, where it indicates that the data consists just of a shape, with no interesting payload. For example, if Tree is declared as above, then Tree () is the type of binary tree shapes, storing nothing of interest at nodes. Similarly [()] is the type of lists of dull elements, and if there is nothing of interest in a list's elements, then the only information it contributes is its length.
To sum up, () is a type. Its one value, (), happens to have the same name, but that's ok because the type and expression languages are separate. It's useful to have a type representing "no information" because, in context (e.g., of a monad or a container), it tells you that only the context is interesting.
The () type can be thought of as a zero-element tuple. It's a type that can only have one value, and thus it's used where you need to have a type, but you don't actually need to convey any information. Here's a couple of uses for this.
Monadic things like IO and State have a return value, as well as performing side-effects. Sometimes the only point of the operation is to perform a side-effect, like writing to the screen or storing some state. For writing to the screen, putStrLn must have type String -> IO ? -- IO always has to have some return type, but here there's nothing useful to return. So what type should we return? We could say Int, and always return 0, but that's misleading. So we return (), the type that has only one value (and thus no useful information), to indicate that there's nothing useful coming back.
It's sometimes useful to have a type which can have no useful values. Consider if you'd implemented a type Map k v which maps keys of type k to values of type v. Then you want to implement a Set, which is really similar to a map except that you don't need the value part, just the keys. In a language like Java you might use booleans as the dummy value type, but really you just want a type that has no useful values. So you could say type Set k = Map k ()
It should be noted that () is not particularly magic. If you want you can store it in a variable and do a pattern match on it (although there's not much point):
main = do
x <- putStrLn "Hello"
case x of
() -> putStrLn "The only value..."
It is called the Unit type, usually used to represent side effects. You can think of it vaguely as Void in Java. Read more here and here etc. What can be confusing is that () syntactically represents both the type and its only value literal. Also note that it is not similar to null in Java which means an undefined reference - () is just effectively a 0-sized tuple.
I really like to think of () by analogy with tuples.
(Int, Char) is the type of all pairs of an Int and a Char, so it's values are all possible values of Int crossed with all possible values of Char. (Int, Char, String) is similarly the type of all triples of an Int, a Char, and a String.
It's easy to see how to keep extending this pattern upwards, but what about downwards?
(Int) would be the "1-tuple" type, consisting of all possible values of Int. But that would be parsed by Haskell as just putting parentheses around Int, and thus being just the type Int. And values in this type would be (1), (2), (3), etc, which also would just get parsed as ordinary Int values in parentheses. But if you think about it, a "1-tuple" is exactly the same as just a single value, so there's no need to actually have them exist.
Going down one step further to zero-tuples gives us (), which should be all possible combinations of values in an empty list of types. Well, there's exactly one way to do that, which is to contain no other values, so there should be only one value in the type (). And by analogy with tuple value syntax, we can write that value as (), which certainly looks like a tuple containing no values.
That's exactly how it works. There is no magic, and this type () and its value () are in no way treated specially by the language.
() is not in fact being treated as "a null value for any type" in the monads examples in the LYAH book. Whenever the type () is used the only value which can be returned is (). So it's used as a type to explicitly say that there cannot be any other return value. And likewise where another type is supposed to be returned, you cannot return ().
The thing to keep in mind is that when a bunch of monadic computations are composed together with do blocks or operators like >>=, >>, etc, they'll be building a value of type m a for some monad m. That choice of m has to stay the same throughout the component parts (there's no way to compose a Maybe Int with an IO Int in that way), but the a can and very often is different at each stage.
So when someone sticks an IO () in the middle of an IO String computation, that's not using the () as a null in the String type, it's simply using an IO () on the way to building an IO String, the same way you could use an Int on the way to building a String.
Yet another angle:
() is the name of a set which contains a single element called ().
Its indeed slightly confusing that the name of the set and the
element in it happens to be the same in this case.
Remember: in Haskell a type is a set that has its possible values as elements in it.
The confusion comes from other programming languages:
"void" means in most imperative languages that there is no structure in memory storing a value. It seems inconsistent because "boolean" has 2 values instead of 2 bits, while "void" has no bits instead of no values, but there it is about what a function returns in a practical sense. To be exact: its single value consumes no bit of storage.
Let's ignore the value bottom (written _|_) for a moment...
() is called Unit, written like a null-tuple. It has only one value. And it is not called
Void, because Void has not even any value, thus could not be returned by any function.
Observe this: Bool has 2 values (True and False), () has one value (()), and Void has no value (it doesn't exist). They are like sets with two/one/no elements. The least memory they need to store their value is 1 bit / no bit / impossible, respectively. Which means that a function that returns a () may return with a result value (the obvious one) that may be useless to you. Void on the other hand would imply that that function will never return and never give you any result, because there would not exist any result.
If you want to give "that value" a name, that a function returns which never returns (yes, this sounds like crazytalk), then call it bottom ("_|_", written like a reversed T). It could represent an exception or infinity loop or deadlock or "just wait longer". (Some functions will only then return bottom, iff one of their parameters is bottom.)
When you create the cartesian product / a tuple of these types, you will observe the same behaviour:
(Bool,Bool,Bool,(),()) has 2·2·2·1·1=6 differnt values. (Bool,Bool,Bool,(),Void) is like the set {t,f}×{t,f}×{t,f}×{u}×{} which has 2·2·2·1·0=0 elements, unless you count _|_ as a value.
Let's say we want to write a generic property map backed by IO operations,
but for some reason we are required to make the value type polymorphic.
type Key = Int
get:: Key -> v -> IO v -- Takes a key and a default value, return the associated value
put:: Key -> v -> IO () -- store (Key,v) pair doing some IO
Do Free Theorems require that get and put do only trivial things in this case too,
and if so, can we cheat the ghc's type system to implement a real type-indexed
IO database?
Generally, strange things may happen in IO, so I do not think that there is a rigorous notion of Free Theorems involving IO. Anyways, from what I know about IO as it is implemented, assuming the functions do
nothing that can crash (such as doing pointless pointer arithmetic to produce a value of type v),
not use any of the unsafe functions (which generally break any Free Theorems-like reasoning),
do not return bottom (e.g. undefined or an exception) and
do eventually “return”
then the “returned” value will be the parameter.
But this means that it is not possible to implement a type-indexed database using IO.
It would be possible with a Typeable a constraint. In that case, the expected Free Theorem does not hold and a get function would be allowed to return something else than the default value.
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.