I am currently working 99 haskell problems
I cannot understand why am I getting an error in this function :-
repli :: [a] -> Int -> [a]
repli xs n = concatMap (take n . repeat) xs
If you are using the REPL, try
>>> let repli xs n = concatMap (take n . repeat) xs
Writing Haskell in the REPL (ake GHCi) is a bit different to writing it in a file. For one thing, variable bindings and function definitions have to be prefixed with let as in
>>> let a = 1
>>> let f x = x + a
For another, you generally have to enter definitions all on one line. You can separate separate definitions with a semicolon, like this
>>> let a = 1; b = 2
or you can use multi-line mode, like this
>>> :{
>>> let c = 3
>>> d = 4
>>> :}
If you've learnt about monads (have you?) then you can imagine that everything you write in the REPL is part of a do block which is of type IO (), with the statements executed as you type them. So in a file you might write
main :: IO ()
main = do
name <- getLine
let greeting = "Hello " ++ name ++ "!"
putStrLn greeting
whereas in the REPL you would write
>>> name <- getLine
Chris
>>> let greeting = "Hello " ++ name ++ "!"
>>> putStrLn greeting
Hello Chris!
>>>
Related
I am a beginner in Haskell and I wanted to know if it was possible to print individual elements of a given list. I tried solving this problem but have failed. This is the code:
main :: IO()
main = do
let list = [1,2,3]
let size = length list
let temp = print_elem list size
print temp
print_elem :: [Int] -> Int -> Int
print_elem xs x = do
let size = length xs
let idx = size - x
let element = xs !! idx
putStr (show element)
putStr(" ")
let dummy = print_elem (xs (x-1))
return " "
I wanted to print something like this
1 2 3
If I simply use putStr (show list) it will display [1,2,3] and I don't want that.
But when I run this code multiple errors occur
printelem.hs:14:5: error:
* Couldn't match expected type `Int' with actual type `IO b0'
* In a stmt of a 'do' block: putStr (show element)
In the expression:
do let size = length xs
let idx = size - x
let element = xs !! idx
putStr (show element)
....
In an equation for `print_elem':
print_elem xs x
= do let size = ...
let idx = ...
let element = ...
....
|
14 | putStr (show element)
| ^^^^^^^^^^^^^^^^^^^^^
printelem.hs:16:29: error:
* Couldn't match expected type `Int -> [Int]'
with actual type `[Int]'
* The function `xs' is applied to one argument,
but its type `[Int]' has none
In the first argument of `print_elem', namely `(xs (x - 1))'
In the expression: print_elem (xs (x - 1))
|
16 | let dummy = print_elem (xs (x-1))
| ^^^^^^^^
How do you fix this issue?
You are thinking too imperatively. First, you need a list of strings, not a list of integers. That's map:
> map show [1,2,3]
["1","2","3"]
Next, you want to join them into a single, space-separate string. That's Data.List.intercalate:
> import Data.List
> intercalate " " (map show [1,2,3])
"1 2 3"
which you can then pass to putStrLn (print would give you the string representation of the string you already have):
import Data.List
main :: IO()
main = do
let list = [1,2,3]
putStrLn (intercalate " " (map show list))
One way to do it is
> mapM_ putStr (intersperse " " (map show [1,2,3])) >> putStrLn ""
1 2 3
it :: ()
This prints the elements one by one, converted to strings by show, interspersed with the spaces in between.
> intersperse " " (map show [1,2,3])
["1"," ","2"," ","3"]
it :: [[Char]]
mapM_ maps an IO action constructor putStr :: String -> IO () on each of the elements, and executes them all as one combined sequence of actions.
Finally this code prints the newline.
Basically I would like to find a way so that a user can enter the number of test cases and then input their test cases. The program can then run those test cases and print out the results in the order that the test cases appear.
So basically I have main which reads in the number of test cases and inputs it into a function that will read from IO that many times. It looks like this:
main = getLine >>= \tst -> w (read :: String -> Int) tst [[]]
This is the method signature of w: w :: Int -> [[Int]]-> IO ()
So my plan is to read in the number of test cases and have w run a function which takes in each test case and store the result into the [[]] variable. So each list in the list will be an output. w will just run recursively until it reaches 0 and print out each list on a separate line. I'd like to know if there is a better way of doing this since I have to pass in an empty list into w, which seems extraneous.
As #bheklilr mentioned you can't update a value like [[]]. The standard functional approach is to pass an accumulator through a a set of recursive calls. In the following example the acc parameter to the loop function is this accumulator - it consists of all of the output collected so far. At the end of the loop we return it.
myTest :: Int -> [String]
myTest n = [ "output line " ++ show k ++ " for n = " ++ show n | k <- [1..n] ]
main = do
putStr "Enter number of test cases: "
ntests <- fmap read getLine :: IO Int
let loop k acc | k > ntests = return $ reverse acc
loop k acc = do
-- we're on the kth-iteration
putStr $ "Enter parameter for test case " ++ show k ++ ": "
a <- fmap read getLine :: IO Int
let output = myTest a -- run the test
loop (k+1) (output:acc)
allOutput <- loop 1 []
print allOutput
As you get more comfortable with this kind of pattern you'll recognize it as a fold (indeed a monadic fold since we're doing IO) and you can implement it with foldM.
Update: To help explain how fmap works, here are equivalent expressions written without using fmap:
With fmap: Without fmap:
n <- fmap read getLine :: IO [Int] line <- getLine
let n = read line :: Int
vals <- fmap (map read . words) getLine line <- getLine
:: IO [Int] let vals = (map read . words) line :: [Int]
Using fmap allows us to eliminate the intermediate variable line which we never reference again anyway. We still need to provide a type signature so read knows what to do.
The idiomatic way is to use replicateM:
runAllTests :: [[Int]] -> IO ()
runAllTests = {- ... -}
main = do
numTests <- readLn
tests <- replicateM numTests readLn
runAllTests tests
-- or:
-- main = readLn >>= flip replicateM readLn >>= runAllTests
For this function,showGame, and the expected output, anyone can give me a hand to make this work ?
import System.IO
type Symbol = Int
showGame :: [Symbol] => IO ()
showGame xs =
let x = mapM_ (replicate '*') xs
putStrLn x
The output should be:
1: *
2: **
3: ***
with
[Symbol] = [1,2,3]
After fixing a few mistakes in your code we get this:
type Symbol = Int
showGame :: [Symbol] -> IO ()
showGame xs =
mapM_ (\x -> putStrLn $ show x ++ ": " ++ replicate x '*') xs
main = showGame [1..3]
Output:
1: *
2: **
3: ***
It looks like you want:
let x = fmap (flip replicate $ '*') [1,2,3]
mapM_ putStrLn x
mapM_ applies a monadic action over a list but discards the results. This is what you want to print, since there is no useful result. However you do want the a result when creating the lists to display. Here you can just use fmap (or map since the input is a list) to create a list for each input list element.
As I am working on learning Haskell, I understand it is a purely functional language. I am having trouble understanding why let-statements don't violate purity.
For example (in ghci):
Prelude> let e = exp 1
Prelude> e
2.718281828459045
Prelude> let e = 2
Prelude> e
2
isn't my second let statement producing a side effect? Or is the second let statement a new closure?
Your second let creates a new binding for e that shadows the existing variable. It does not modify e. You can easily check this with the following:
Prelude> let e = 1
Prelude> let f () = "e is now " ++ show e
Prelude> f ()
"e is now 1"
Prelude> let e = 2
Prelude> e
2
Prelude> f ()
"e is now 1"
Prelude>
let introduces a new local variable with a single unalterable value, and it has more local scope than any surrounding definitions, so for example:
*Main> (let length = 2 in show length) ++ ' ':show (length "Hello")
"2 5"
Here the first length has the value 2, but its scope local to the brackets. Outside the brackets, length means what it has always meant. Nothing has been edited, just a more local variable has been introduced that happens to have the same name as another one in a different scope. Let's make ghci mad by omitting the brackets and making it try to make length a number and a function:
*Main> let length = 2 in show length ++ ' ':show (length "Hello")
<interactive>:1:14:
No instance for (Num ([Char] -> a0))
arising from the literal `2'
Possible fix: add an instance declaration for (Num ([Char] -> a0))
In the expression: 2
In an equation for `length': length = 2
In the expression:
let length = 2 in show length ++ ' ' : show (length "Hello")
<interactive>:1:19:
No instance for (Show ([Char] -> a0))
arising from a use of `show'
Possible fix: add an instance declaration for (Show ([Char] -> a0))
In the first argument of `(++)', namely `show length'
In the expression: show length ++ ' ' : show (length "Hello")
In the expression:
let length = 2 in show length ++ ' ' : show (length "Hello")
And here's your example:
*Main> let e = exp 1 in show e ++ " " ++ let e = 2 in show e
"2.718281828459045 2"
I'll add brackets to emphasise the scope:
*Main> let e = exp 1 in (show e ++ " " ++ (let e = 2 in (show e)))
"2.718281828459045 2"
The first e is hidden rather than edited. Referential transparency is preserved, but it's definitely bad practice because it's hard to follow.
Now secretly the interactive prompt is a bit like one big do block in the IO monad, so let's look at that:
testdo = do
let e = exp 1
print e
let e = 2
print e
Now I have to admit that looks an awful lot like breaking referential transparency, but bear in mind that this looks like it does too:
testWrite = do
writeFile "test.txt" "Hello Mum"
xs <- readFile "test.txt"
print xs
writeFile "test.txt" "Yo all"
xs <- readFile "test.txt"
print xs
Now in what sense have we got referential transparency? xs clearly refers to two different strings. Well, what does this do notation actually mean? It's syntactic sugar for
testWrite = writeFile "test.txt" "Hello Mum"
>> readFile "test.txt"
>>= (\xs -> print xs
>> writeFile "test.txt" "Yo all"
>> readFile "test.txt"
>>= (\xs -> print xs))
Now it's clearer that what looks like assignment is just local scope again. You presumably are happy to do
increment :: [Int] -> [Int]
increment = \x -> map (\x -> x+1) x
Which is doing the same thing.
Summary
What appeared to be assignment is just introduction of a new local scope. Phew. If you use this a lot, you make it very unclear what your code means.
I'm using the lines functionality to take an input and split up many variables before sending it off to a function. Please look at the run function and tell me why I get the following error. It seems like it should just assign the first string in ln to seq, but I get an error.
ERROR:dishonest.hs:33:11:
Couldn't match expected type `[t]' against inferred type `Char'
In a 'do' expression: seq <- ln !! 0
In the expression:
do ln <- lines s
seq <- ln !! 0
states <- ln !! 1
l1 <- listDouble (ln !! 2)
....
In the definition of `run':
run s = do ln <- lines s
seq <- ln !! 0
states <- ln !! 1
....
code follows...
import Char
maximumInd :: (Double, Double) -> Int
maximumInd (d1,d2) | maximum [d1,d2] == d1 = 1
| maximum [d1,d2] == d2 = 2
scoreFunction :: String -> Int -> [Double] -> [Double] -> Double -> Double -> (Double,Double)
scoreFunction string (-1) l1 l2 t1 t2 = (0.5, 0.5)
scoreFunction string index l1 l2 t1 t2 = ((fst (scoreFunction string (index-1) l1 l2 t1 t2)) * (l1!!num) * (tr (maximumInd (scoreFunction string (index-1) l1 l2 t1 t2))!!1), (snd (scoreFunction string (index-1) l1 l2 t1 t2)) * (l2!!num) * (tr (maximumInd (scoreFunction string (index-1) l1 l2 t1 t2))!!2))
where
num = digitToInt (string!!index)
tr n | n == 1 = l1
| n == 2 = l2
--split is stolen from teh webs http://julipedia.blogspot.com/2006/08/split-function-in-haskell.html
split :: String -> Char -> [String]
split [] delim = [""]
split (c:cs) delim
| c == delim = "" : rest
| otherwise = (c : head rest) : tail rest
where
rest = split cs delim
readDouble :: String -> Double
readDouble s = read s :: Double
listDouble :: String -> [Double]
listDouble s = map readDouble $ split s ' '
run :: String -> String
run s = do
ln <- lines s
seq <- ln!!0
states <- ln!!1
l1 <- listDouble (ln!!2)
l2 <- listDouble (ln!!3)
tr1 <- readDouble (ln!!4)
tr2 <- readDouble (ln!!5)
show maximumInd (scoreFunction seq (length seq) l1 l2 tr1 tr2)
main = do
putStrLn "Please compose a test job for Viterbi."
putStrLn "First line: A sequence with language [1,9]."
putStrLn "Second line: The number of states."
putStrLn "For the next 2 lines: space delimited emission probabilities."
putStrLn "For the 2 lines after that, transmission probabilities."
putStrLn "Then do ./casino < filename "
interact run
First, let's look at how the compiler is interpreting it:
run :: String -> String
String is in fact [Char].
run s = do
ln <- lines s
...
Simplifying things a lot, a do block must "run" in a Monad. This means that it "returns" a value of type (Monad t) => t a. Since this function is returning [Char], the do block will return [Char], meaning the Monad is [] (if you read [a] as [] a, it will be more clear).
Copying from another answer of mine,
Simplifying things a lot, on a do block on the IO monad, every line is either:
Something which returns a value of the "IO a" type; the value of the "a" type within it is discarded (so the "a" is often "()")
A <- expression, which does the same thing but instead of discarding the value of the "a" type gives it the name to the left of the <-
A let, which does nothing more than give a name to a value
Here we are not on the IO Monad, but on the [] Monad. So the expression to the right of the <- must be a [a].
So, in the first line of the do block:
ln <- lines s
Here the type is [[Char]], and so the type of ln is [Char].
On the next line:
seq <- ln!!0
Here ln!!0 has type Char, but since you are in the [] Monad, it is expecting a list of some sort. This is what causes the compiler's error message.
The solution is to, instead of using the do notation, use a plain let block:
run :: String -> String
run s = let
ln = lines s
seq = ln!!0
states = ln!!1
l1 = listDouble (ln!!2)
l2 = listDouble (ln!!3)
tr1 = readDouble (ln!!4)
tr2 = readDouble (ln!!5)
in show maximumInd (scoreFunction seq (length seq) l1 l2 tr1 tr2)
I did not compile this block, but even if there is something else wrong with it, it should be enough to get you going again.
I'm not sure if this is right, but the issue might lay in the fact that <- isn't an assignment operator, as you seem to be using it; it essentially unpacks a value from a monad. But I'm not really sure if that's the cause of your issue or not.
Yeah i think mipadi is right. the do notation translates into >>= and return calls to the list monad.
run s = do
ln <- lines s
seq <- ln!!0
states <- ln!!1
Will get the list that is returned by lines s and for the seq and states, ln will be a string of that list each time. So actually with ln!!0, you get the first character of that string. But a list is required at the right side of the <- there. That's just about all what i remember. Has been quite a bit of time since i did those stuff with haskell :)
Remember that lists are monads in haskell, with the definition:
instance Monad [] where
m >>= f = concatMap f m
return x = [x]
fail s = []
So if you take your code, which goes something like:
do {ln <- lines "hello, world"; ln!!0}
That is equivalent to the following using bind notation:
lines "hello world" >>= (\ln -> ln!!0)
or more concisely:
lines "hello world" >>= (!!0)
We can now use the definition of the list monad to re-write that as the following:
concatMap (!!0) (lines "hello, world")
Which is equivalent to:
concat $ map (!!0) (lines "hello, world")
lines "hello, world" will return ["hello, world"], so mapping (!!0) over it will produce the string "h". That has type [Char], but concat requires a type [[t]]. Char does not match [t], hence the error.
Try using a let or something rather than do notation.
Edit:
So I think this is what you want, using let rather than do.
run :: String -> String
run s = let ln = lines s
seq = ln!!0
states = ln!!1
l1 = listDouble (ln!!2)
l2 = listDouble (ln!!3)
tr1 = readDouble (ln!!4)
tr2 = readDouble (ln!!5)
in show $ maximumInd (scoreFunction seq (length seq) l1 l2 tr1 tr2)
run is of type String -> String, so you probably don't want the do notation[1]. I'd advise you to do this:
comment out everything below the
listDouble function, load that, and
be sure that'll compile.
add a test value that's formatted like the file you expect. Something like:
t = "[1,9]\n3\n1.0 1.0 1.0\n1.0 1.0 1.0\n1.0\n1.0"
add a test values that the top level for the values you're defining in run
ln = lines t
seq = ln!!0
states = ln!!1
l1 = listDouble (ln!!2)
l2 = listDouble (ln!!3)
tr1 = readDouble (ln!!4)
tr2 = readDouble (ln!!5)
use the type signature of
scoreFunction to guide you in
building the arguments to that
function, then the rest of run, and finally main.
Learn to use an interpreter, such as Hugs, ghci. Learn the :r and :t commands. For example (i'm using currying to give some but not all of a functions arguments):
:t scoreFunction
:t scoreFunction ""
:t scoreFunction 3445
You can use this to have the system help you determine if you're on the right track.
Doing this at the top level with introduce a conflict with a Prelude.seq function - either rename your seq, or refernence yours as Main.seq.
Haskell is notorious for error messages that are inscrutable to beginners, so I'd recommend periodically rolling back to a version that compiles, either by commenting out your current experiments (which is what I had you do in step 1 above), or using your editors undo function.
[1]I say probably because Strings, being lists of Characters, are instances of the Monad class, but that's fairly advanced