Title: Haskell string list through lines
Tags: string;haskell;functional-programming
Question: 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 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 (Double, Double) -> Int
maximumInd (d1,d2) | maximum [d1,d2] == d1 = 1
| maximum [d1,d2] == d2 = 2
scoreFunction 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 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 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 String -> Char -> [String]
split [] delim = [""]
split (c:cs) delim
| c == delim = "" : rest
| otherwise = (c : head rest) : tail rest
where
rest = split cs delim
readDouble 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 String -> Double
readDouble s = read s 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 Double
listDouble 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 String -> [Double]
listDouble s = map readDouble $ split s ' '
run 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 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


Here is another answer: 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

Here is another answer: 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.

Here is another answer: 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 :)

Here is another answer: First, let's look at how the compiler is interpreting it:
run 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 String -&gt; 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) =&gt; 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 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 String -&gt; 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.

Here is another answer: Remember that lists are monads in haskell, with the definition:
instance Monad [] where
m &gt;&gt;= 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" &gt;&gt;= (\ln -&gt; ln!!0)
or more concisely:
lines "hello world" &gt;&gt;= (!!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.
So I think this is what you want, using let rather than do.
run 75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0 String -&gt; 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)
Comment for this answer: Thanks for refreshing my memory with how do translates into what the monad wants. Can you maybe point out how the let stuff translates too? I think that will help him and me too :)
Comment for this answer: Tho i think using let in a do notation just translates to
let ..... in do .... . i slightly remember that
Comment for this answer: I don't think let expressions actually translate down to any more primitive forms (I may be wrong), It's just a basic language construct. I updated my post to show what I think the OP wanted.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 5, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 2.5', 'CreationDate': '2008:00:11/16/08', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<string><haskell><functional-programming>', 'Title': 'Haskell string list through lines', 'ViewCount': 2006, 'id': 293345, 'user_AboutMe': '', 'user_AccountId': 17071.0, 'user_DisplayName': 'Overflown', 'user_Reputation': 1830.0, 'user_Views': 290.0, 'user_id': 37840.0}}