I have made the following haskell program which will do some basic operations of load, read and increment. I am getting a type error. Can someone please tell why type error is there and how can i resolve it.
module ExampleProblem (Value,read',load,incr) where
newtype Value a = Value Int deriving (Eq,Read,Show)
read':: Value Int -> Int
read' (Value a) = a
load:: Int -> Value Int
load a = Value a
incr:: Value Int -> Value Int
incr (Value a) = Value (a+1)
main = do
(Value ab) <- (load 42)
if (read'( Value ab) /= 42)
then show "Failure to load"
else do
Value b <- incr( Value ab)
Value c <- incr( Value b)
if ((Value c) == Value 44)
then show "Example finished"
else show "error"
return
The error i get is:
Couldn't match expected type `Int' with actual type `Value t0'
In the pattern: Value ab
In a stmt of a 'do' expression: (Value ab) <- (load 42)
In the expression:
do { (Value ab) <- (load 42);
if (read' (Value ab) /= 42) then
show "Failure to load"
else
do { Value b <- incr (Value ab);
.... } }
And when i made a separate file in which i had written the main function i was getting the error of scope although i was importing the module ExampleProblem.
Not in scope: data constructor `Value'
It seems you are confused about how to use do-notation. Do-notation is used for composing actions in a monad. In the case of main, that monad will be IO so I'll be sticking with IO to keep things simple.
There are three types of statements you can use in do-notation:
x <- foo binds the result of running the action foo to the pattern x. foo must have type IO Something, and x will then have the corresponding type Something.
let x = foo binds a value without anything special happening. This is the same as = at the top level, except that any preceding bindings are in scope.
foo runs an action of type IO Something. If it's the last statement in the do-block, this becomes the result of the block, otherwise the result is ignored.
The main problem in your code is that you're using x <- foo statements with things that aren't IO actions. That won't work. Instead, use the let x = foo form.
Secondly, show is also not an IO action. It's just a function that converts stuff to String. You probably meant to use putStrLn which will print a string to standard output.
Thirdly, return is not a statement like in C or Java. It's a function which, given a value, produces an action that does nothing and returns the value. It is often used as the last thing in a do-block when you want it to return a pure value. Here it is unnecessary.
And finally, if you want to run this code, your module must be called Main and it must export the main function. The easiest way of doing this is just to remove the module ... where line and the name will default to Main. You typically only want this line with the in modules in your project which don't contain main.
main = do
let Value ab = load 42
if read' (Value ab) /= 42
then putStrLn "Failure to load"
else do
let Value b = incr (Value ab)
let Value c = incr (Value b)
if Value c == Value 44
then putStrLn "Example finished"
else putStrLn "error"
This should work, but you're needlessly wrapping and unwrapping your values in the Value type. Perhaps you intended something like this:
main = do
let ab = load 42
if read' ab /= 42
then putStrLn "Failure to load"
else do
let b = incr ab
let c = incr b
if c == Value 44
then putStrLn "Example finished"
else putStrLn "error"
I'll start with your second question.
newtype Value a = Value Int deriving (Eq,Read,Show)
This actually creates two Values:
the Value in newtype Value a is a type constructor
the Value in Value Int is a data constructor (usually just call it a constructor)
They are different things!
module ExampleProblem (Value,read',load,incr) where
Here Value means the type constructor. To export the data constructor as well, you need
module ExampleProblem (Value(Value),read',load,incr) where
Now, about your first question.
main must have type IO something
You've set main to be a do block, so that means
everything to the right of an <- must have type IO somethingOrOther
The line with the error message is
(Value ab) <- (load 42)
load 42 has type Value Int, clearly nothing to do with IO, so you get an error.
So how do you fix this?
if a line of code in a do block is not an IO statement, it must be a let statement1
Other errors you need to fix:
return doesn't do what it does in every other language.
In particular, it always takes a value to return.
We should have called it something else. Sorry about that.
Imagine it's called pure instead. Anyway, you don't need it here.
to print a String to the screen, you should use putStrLn, not show.
Ghci prints the return value of expressions you give it, but this is a program in its own right,
so you have to do the IO yourself.
then and else need to be indented further than the if (I think this rule is changing, but I don't think it has yet)
So we end up with
main = do
let Value ab = load 42
if read' (Value ab) /= 42
then putStrLn "Failure to load"
else do
let Value b = incr (Value ab)
let Value c = incr (Value b)
if Value c == Value 44
then putStrLn "Example finished"
else putStrLn "error"
Footnotes:
Not strictly true: do blocks can be used for things other than IO. But you'll learn about that later.
One additional remark: You should try to do as much work outside the main-IO thing as possible. In your case it's easy: You have a calculation which takes no argument and produces a String (which should be printed out). If you had different "outcomes", you could use e.g. Either, but here we are fine with just String as return type.
As hammar pointed out it makes not much sense to pattern match and reconstruct Value all the way, just use the values as they are, and use pattern matching only if you need to access the number inside.
The type Value doesn't need to be polymorphic if it always wraps just an Int, so I dropped the a. Else you have something called a "phantom type", which is possible and sometimes even useful, but definitely not here (of course if you want to be able to wrap arbitrary types, you can write data Value a = Value a).
So here is a version which does only the bare minimum in IO, and keeps everything else pure (and hence flexible, testable etc):
data Value = Value Int deriving (Eq,Read,Show)
read':: Value -> Int
read' (Value a) = a
load:: Int -> Value
load a = Value a
incr:: Value -> Value
incr (Value a) = Value (a+1)
main = putStrLn calc
calc :: String
calc = let ab = load 42
in if read' ab /= 42 then "Failure to load" else increaseTwice ab
increaseTwice :: Value -> String
increaseTwice v = let b = incr v
c = incr b
in if c == Value 44 then "Example finished" else "error"
I can't use Haskell here, so I hope this works...
Related
I need one function which read a file and return the number of lines in that file but it will not take anything as an argument.I have written this code but i am getting the error that couldnt match type IO Int with Int.
I am calling this function from another function as
let r=row'
Help me to figure it out
Thanks`
row'::()->Int
row' ()=do
content<-readFile "sample.txt"
let line_file=lines content
return (length line_file)
The problem here is that readFile and return are IO functions, and any function that performs IO in Haskell has to denote this in its type. You could instead write your function as
row' :: IO Int
row' = do
content <- readFile "sample.txt"
let line_file = lines content
return (length line_file)
And this would compile just fine. This restriction in the type signature is there to ensure that any function that has side effects or can return different values for the same input is sectioned off by the type system. This can greatly help in reasoning about your code, since for a pure function, such as
countRows :: String -> Int
countRows content = length (lines content)
Can always be guaranteed to return the same result for the same input. Then you can use these "pure" functions in "impure" functions to perform the actual calculations, keeping all the "impure" side effects contained to a single location:
row'' :: IO Int
row'' = do
content <- readFile "sample.txt"
return (countRows content)
Now row'' doesn't do anything other than read the file and pass the contents to a function that actually performs the work of counting the lines in that file. You could even state this more simply using fmap as
row'' :: IO Int
row'' = fmap countRows $ readFile "sample.txt"
To use this function, you can do something like
main :: IO ()
main = do
putStrLn "Counting the number of rows in sample.txt"
r <- row''
putStrLn $ "There are " ++ show r ++ " row(s) in sample.txt"
But note that row'' must be called from another IO function, you can not use it as
-- THIS IS WRONG, WON'T COMPILE
doubleRows :: Int
doubleRows = rows'' * 2
-- THIS IS WRONG TOO
doubleRows' :: Int
doubleRows' = do
r <- rows''
return (r * 2)
because both of these examples would have to have the type IO Int instead, and the first one wouldn't compile even with the right type signature because IO Int * Int doesn't make any sense, you have to first "extract" the Int from IO Int using the bind syntax of r <-.
I'm trying to do a function which returns true or false.
owlFile = ".+\\.owl"
testOwlFile src = src =~ owlFile :: Bool
And i need to use on my do block :
main = do
[src] <- getArgs
resTestOwlFile <- testOwlFile
if resTestOwlFile
then do ontology <- runX(readDocument [withValidate no,withRemoveWS yes ] src >>> getontology)
else print "error"
But i'm having an error which is Couldn't match excepted type IO BOOL with actual type Bool In the return type of a call of "testOwlFile"
What can i do for that ?
Please avoid, generally, to think about "converting". Sometimes you actually need to do that, but normally the type system gives you just the right type at the right spot if you use it correctly.
IO Bool is not a boolean value, but an action that, possibly together with side effects, will also yield a boolean value. So why would you "convert" a perfectly good pure value to such an action, one that doesn't actually do any of the stuff it's type is there for? That doesn't make much sense. The right thing to do, as already said, is to use the value directly; I'd just put it straight in the if condition:
main = do
[src] <- getArgs
if src =~ owlFile
then ...
else ...
That said, this conversion Bool -> IO Bool, however useless, is certainly possible. Indeed, for any monad1 m, that is one of the fundamental operations:
class Monad m where
return :: a -> m a
So you could in principle write
resTestOwlFile <- return testOwlFile
But don't. That is always equivalent to let resTestOwlFile = testOwlFile (guaranteed by the monad laws).
1
The weaker Applicative is actually sufficient.
The problem is that testOwlFile is of type Bool, but the <- notation expects an IO something.
If testOwlFile did have type IO Bool, then resTestOwlFile would have type Bool and your code would have built fine.
As #user2407038 pointed out in a comment, you can use let instead of <- when the thing you are defining has the same type as the expression you are defining it with:
let resTestOwlFile = testOwlFile
Or you could just use testOwlFile directly in the if statement on the next line.
Note that more generally the <- notation expects m something for any m that's an instance of the Monad class, but in this case m must be IO because you're defining the main function and because of other code in the do block like getArgs and print.
///Edit
I have a problem with haskell. If someone can help me, that would be great.
I'm inserting records into a file using the following code:
check :: Int -> Int
check a
|a > 0 && a<=10 = a
|otherwise = error "oh. hmm.. enter a number from the given interval"
ame :: IO ()
ame = do
putStr "Enter the file name: "
name <- getLine
putStrLn "Do you want to add new records? "
question <- getLine
if question == "yes" then do
putStrLn "Enter your records:"
newRec <- getLine
appendFile name ('\n':newRec)
--new lines--
putStrLn "enter a number between 0 and 10: "
something <- getLine
return (read something:: Int)
let response = check something
putStrLn response
appendFile name ('\n':something)
putStrLn "enter something new again: "
something2 <- getLine
appendFile name ('\n':something2)
putStrLn "a"
else
putStr "b"
Now I want to extract some records from this file, using a specific criteria. For example, i want to extract and display records from even(or odd or any other criteria) rows. can I do that? if yes, how?
Also...
I want to check the user input. Let's say that I don't want him/her to enter a string instead of an integer. can I also check his/her input? do I need to create another function and call that function inside the code from above?
///Edit
thank you for answering. but how can i embed it into my previous code?
I've tried now to create a function(you can see the above code) and then call that function in my IO. but it doesn't work..
Yes, it is certainly possible to display only certain rows. If you want to base it off of the row number, the easiest way is to use zip and filter
type Record = String
onlyEven :: [Record] -> [Record]
onlyEven records =
map snd $ -- Drop the numbers and return the remaining records
filter (even . fst) $ -- Filter by where the number is even
zip [1..] -- All numbers
records -- Your records
This technique can be used in a lot of circumstances, you could even abstract it a bit to
filterByIdx :: Integral i => (i -> Bool) -> [a] -> [a]
filterByIdx condition xs = map snd $ filter (condition . fst) $ zip [1..] xs
-- Could also use 0-based of `zip [0..] xs`, up to you
onlyEven :: [a] -> [a]
onlyEven = filterByIdx even
If you want to check if an input is an Int, the easiest way is to use the Text.Read.readMaybe function:
import Text.Read (readMaybe)
promptUntilInt :: IO Int
promptUntilInt = do
putStr "Enter an integer: "
response <- getLine
case readMaybe response of
Just x -> return x
Nothing -> do
putStrLn "That wasn't an integer!"
promptUntilInt
This should give you an idea of how to use the function. Note that in some cases you'll have to specify the type signature manually as case (readMaybe response :: Maybe Int) of ..., but here it'll work fine because it can deduce the Int from promptUntilInt's type signature. If you get an error about how it couldn't figure out which instance for Read a to use, you need to manually specify the type.
You have
something <- getLine
return (read something:: Int)
let response = check something
putStrLn response
To step through what you're trying to do with these lines:
something <- getLine
getLine has the type IO String, meaning it performs an IO action and returns a String. You can extract that value in do notation as
something <- getLine
Just as you have above. Now something is a String that has whatever value was entered on that line. Next,
return (read something :: Int)
converts something to an Int, and then passes it to the function return. Remember, return is not special in Haskell, it's just a function that wraps a pure value in a monad. return 1 :: Maybe Int === Just 1, for example, or return 1 :: [Int] === [1]. It has contextual meaning, but it is no different from the function putStrLn. So that line just converts something to an Int, wraps it in the IO monad, then continues on to the next line without doing anything else:
let response = check something
This won't compile because check has the type Int -> Int, not String -> String. It doesn't make any sense to say "hello, world" > 0 && "hello, world" <= 10, how do you compare a String and an Int? Instead, you want to do
let response = check (read something)
But again, this is unsafe. Throwing an error on an invalid read or when read something is greater than 10 will crash your program completely, Haskell does errors differently than most languages. It's better to do something like
check :: Int -> Bool
check a = a > 0 && a <= 10
...
something <- getLine
case readMaybe something of
Nothing -> putStrLn "You didn't enter a number!"
Just a -> do
if check a
then putStrLn "You entered a valid number!"
else putStrLn "You didn't enter a valid number!"
putStrLn "This line executes next"
While this code is a bit more complex, it's also safe, it won't ever crash and it handles each case explicitly and appropriately. By the way, the use of error is usually considered bad, there are limited capabilities for Haskell to catch errors thrown by this function, but errors can be represented by data structures like Maybe and Either, which give us pure alternatives to unsafe and unpredictable exceptions.
Finally,
putStrLn response
If it was able to compile, then response would have the type Int, since that's what check returns. Then this line would have a type error because putStrLn, as the name might suggest, puts a string with a new line, it does not print Int values. For that, you can use print, which is defined as print x = putStrLn $ show x
Since this is somewhat more complex, I would make a smaller function to handle it and looping until a valid value is given, something like
prompt :: Read a => String -> String -> IO a
prompt msg failMsg = do
putStr msg
input <- getLine
case readMaybe input of
Nothing -> do
putStrLn failMsg
prompt
Just val -> return val
Then you can use it as
main = do
-- other stuff here
-- ...
-- ...
(anInt :: Int) <- prompt "Enter an integer: " "That wasn't an integer!"
-- use `anInt` now
if check anInt
then putStrLn $ "Your number multiplied by 10 is " ++ show (anInt * 10)
else putStrLn "The number must be between 1 and 10 inclusive"
You don't have to make it so generic, though. You could easily just hard code the messages and the return type like I did before with promptUntilInt.
I have a hard time grasping this. When writing in do notation, how are the following two lines different?
1. let x = expression
2. x <- expression
I can't see it. Sometimes one works, some times the other. But rarely both. "Learn you a haskell" says that <- binds the right side to the symbol on the left. But how is that different from simply defining x with let?
The <- statement will extract the value from a monad, and the let statement will not.
import Data.Typeable
readInt :: String -> IO Int
readInt s = do
putStrLn $ "Enter value for " ++ s ++ ": "
readLn
main = do
x <- readInt "x"
let y = readInt "y"
putStrLn $ "x :: " ++ show (typeOf x)
putStrLn $ "y :: " ++ show (typeOf y)
When run, the program will ask for the value of x, because the monadic action readInt "x" is executed by the <- statement. It will not ask for the value of y, because readInt "y" is evaluated but the resulting monadic action is not executed.
Enter value for x:
123
x :: Int
y :: IO Int
Since x :: Int, you can do normal Int things with it.
putStrLn $ "x = " ++ show x
putStrLn $ "x * 2 = " ++ show (x * 2)
Since y :: IO Int, you can't pretend that it's a regular Int.
putStrLn $ "y = " ++ show y -- ERROR
putStrLn $ "y * 2 = " ++ show (y * 2) -- ERROR
In a let binding, the expression can have any type, and all you're doing is giving it a name (or pattern matching on its internal structure).
In the <- version, the expression must have type m a, where m is whatever monad the do block is in. So in the IO monad, for instance, bindings of this form must have some value of type IO a on the right-hand side. The a part (inside the monadic value) is what is bound to the pattern on the left-hand side. This lets you extract the "contents" of the monad within the limited scope of the do block.
The do notation is, as you may have read, just syntactic sugar over the monadic binding operators (>>= and >>). x <- expression de-sugars to expression >>= \x -> and expression (by itself, without the <-) de-sugars to expression >>. This just gives a more convenient syntax for defining long chains of monadic computations, which otherwise tend to build up a rather impressive mass of nested lambdas.
let bindings don't de-sugar at all, really. The only difference between let in a do block and let outside of a do block is that the do version doesn't require the in keyword to follow it; the names it binds are implicitly in scope for the rest of the do block.
In the let form, the expression is a non-monadic value, while the right side of a <- is a monadic expression. For example, you can only have an I/O operation (of type IO t) in the second kind of binding. In detail, the two forms can be roughly translated as (where ==> shows the translation):
do {let x = expression; rest} ==> let x = expression in do {rest}
and
do {x <- operation; rest} ==> operation >>= (\ x -> do {rest})
let just assigns a name to, or pattern matches on arbitrary values.
For <-, let us first step away from the (not really) mysterious IO monad, but consider monads that have a notion of a "container", like a list or Maybe. Then <- does not more than "unpacking" the elements of that container. The opposite operation of "putting it back" is return. Consider this code:
add m1 m2 = do
v1 <- m1
v2 <- m2
return (v1 + v2)
It "unpacks" the elements of two containers, add the values together, and wraps it again in the same monad. It works with lists, taking all possible combinations of elements:
main = print $ add [1, 2, 3] [40, 50]
--[41,51,42,52,43,53]
In fact in case of lists you could write as well add m1 m2 = [v1 + v2 | v1 <- m1, v2 <- m2]. But our version works with Maybes, too:
main = print $ add (Just 3) (Just 12)
--Just 15
main = print $ add (Just 3) Nothing
--Nothing
Now IO isn't that different at all. It's a container for a single value, but it's a "dangerous" impure value like a virus, that we must not touch directly. The do-Block is here our glass containment, and the <- are the built-in "gloves" to manipulate the things inside. With the return we deliver the full, intact container (and not just the dangerous content), when we are ready. By the way, the add function works with IO values (that we got from a file or the command line or a random generator...) as well.
Haskell reconciles side-effectful imperative programming with pure functional programming by representing imperative actions with types of form IO a: the type of an imperative action that produces a result of type a.
One of the consequences of this is that binding a variable to the value of an expression and binding it to the result of executing an action are two different things:
x <- action -- execute action and bind x to the result; may cause effect
let x = expression -- bind x to the value of the expression; no side effects
So getLine :: IO String is an action, which means it must be used like this:
do line <- getLine -- side effect: read from stdin
-- ...do stuff with line
Whereas line1 ++ line2 :: String is a pure expression, and must be used with let:
do line1 <- getLine -- executes an action
line2 <- getLine -- executes an action
let joined = line1 ++ line2 -- pure calculation; no action is executed
return joined
Here is a simple example showing you the difference.
Consider the two following simple expressions:
letExpression = 2
bindExpression = Just 2
The information you are trying to retrieve is the number 2.
Here is how you do it:
let x = letExpression
x <- bindExpression
let directly puts the value 2 in x.
<- extracts the value 2 from the Just and puts it in x.
You can see with that example, why these two notations are not interchangeable:
let x = bindExpression would directly put the value Just 2 in x.
x <- letExpression would not have anything to extract and put in x.
I understand how to use recursive data structures to manage a list of thingies:
data Thingy a = NoThingy | Thingy a a (Thingy a) deriving (Show, Read)
firstThingsFirst :: a -> a -> (Thingy a)
firstThingsFirst a b = Thingy a b NoThingy
andAnotherThing :: a -> a -> Thingy a -> Thingy a
andAnotherThing a b NoThingy = Thingy a b NoThingy
andAnotherThing a b things = Thingy a b things
And in ghci I can do something like:
let x=andAnotherThing "thing1" "thing2" NoThingy
let y=andAnotherThing "thing3" "thing4" x
However, I don't know how to make this work for a compiled program which takes user input. In other words, I want to let a user fill up the structure. Something like:
import System.IO
allThings=NoThingy
main = do
putStrLn "First Thing"
first<-getLine
putStrLn "Second Thing"
second<-getLine
let allThings=Thingy first second allThings
print allThings
main
Values in Haskell are immutable, so if you "add an item to a list", you get a new list. So in your code above, the
let allThings = Thingy first second allThings
doesn't do what you expect. The top-level allThings has the value NoThingy and that cannot change. The name allThings in the let-binding doesn't refer to the top-level entity, it introduces a new binding shadowing the top-level name, and that new name is also referenced on the right hand side of the binding.
So that line and the following are equivalent to
let theThings = Thingy first second theThings
print theThings
The let-binding creates a cyclic structure, referring to itself as one of its components. That means of course that printing it will never finish.
What you (probably) want to do requires passing the structure you want to update as a parameter
loop things = do
putStrLn "First Thing"
...
let newThings = Thingy first second things
print newThings
loop newThings
And of course, like Nicolas said, you probably want to convert the input strings to values of appropriate type.
What you create is an infinitely self-referential "allThings" that gets printed.
You are binding to the name allThings twice. The first time before main and the second time before print.
The second binding refers to allThings at then end of the right hand side. This reference is NOT to the first binding. This reference is to the second binding itself.
If you change the name of the second binding and of the print:
main = do
putStrLn "First Thing"
first <- getLine
putStrLn "Second Thing"
second <- getLine
let allThings2 = Thingy (read first) (read second) allThings
print allThings2
main
then you will get a single Thingy printed on each loop of main. Since you want to accumulate the answers you can define a tail-recursive "query" like this:
query old = do
putStrLn "First Thing"
first<-getLine
putStrLn "Second Thing"
second<-getLine
let new=Thingy first second old
print new
query new
main = query NoThingy
The above may do what you are looking for.
It sounds like you're asking for a way to convert from user input of type String to a value of type Thingy. Since your Thingy type already has an instance for Read, you can use the read function:
read :: Read a => String -> a
This makes your main function more like:
main = do
putStrLn "First Thing"
first <- getLine
putStrLn "Second Thing"
second <- getLine
let allThings = Thingy (read first) (read second) allThings
print allThings
main
Of course, if you enter a string that doesn't correspond to a Thingy, then you'll get an error, so you might want to use readMay from the safe package instead:
readMay :: Read a => String -> Maybe a
Another problem is that the type inference can't guess which type a is intended, so you'll also have to give it a hint, by maybe having something like:
let allThings = Thingy (read first :: Int) (read second :: String) allThings
It's probably worth noting that in this definition, allThings is an infinite structure, and will take forever to print: the last call to main will never be reached.
The problem is that you are trying to use a variable to hold mutable state (like one would do in an imperative language) but you can't do so in Haskell. All state must be explicitly passed as arguments to your functions. As pointed in the other answers, the allThings inside main is actually a separate variable from the allThings in the global scope (it just shadows the same name)
The following example shows how to build a program that loops forever while building up a list of numbers. I think this is kind of what you want to do and it shouldn't be hard to adapt it to "Thingies"
In our case the state we have to keep for our loop is the index of the next number to be entered (1st, 2nd, etc) and the list of numbers that we have already been read. Our loop function will thus receive this state as an argument and return an IO action.
module Main where
-- Explicit signature so readLn and show don't complain...
loop_step :: (Int, [Int]) -> IO ()
loop_step (i,xs) = do
putStrLn ("Enter the " ++ show i ++ "th number:")
n <- readLn
let newList = n : xs
print newList
loop_step (i+1, newList)
main :: IO ()
main = do
loop_step (1, [])