我正在使用行功能来获取输入并在将许多变量发送到函数之前将其拆分.请查看run函数并告诉我为什么会出现以下错误.看起来它应该只是将ln中的第一个字符串分配给seq,但是我得到一个错误.
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
CesarB.. 5
首先,让我们看一下编译器如何解释它:
run :: String -> String
String
实际上是[Char]
.
run s = do ln <- lines s ...
简化的东西很多,一个do
块必须在"运行" Monad
.这意味着它"返回"一个类型的值(Monad t) => t a
.由于此函数正在返回[Char]
,因此该do
块将返回[Char]
,这意味着Monad
它[]
(如果您读[a]
为[] a
,则会更清楚).
复制我的另一个答案,
在IO monad的do块上简化了很多事情,每一行都是:
返回"IO a"类型值的东西; 其中"a"类型的值被丢弃(因此"a"通常是"()")
一个< - 表达式,它执行相同的操作,但不是丢弃"a"类型的值,而是给出了< - 左侧的名称 -
一个let,它只是给一个值赋一个名字
在这里,我们不是在IO
Monad上,而是在[]
Monad上.因此,权利的表达<-
必须是一个[a]
.
所以,在do
块的第一行:
ln <- lines s
这里的类型是[[Char]]
,所以类型ln
是[Char]
.
在下一行:
seq <- ln!!0
这里ln!!0
有类型Char
,但由于你在[]
Monad,它期待一些类型的列表.这是导致编译器错误消息的原因.
解决方案是do
使用普通let
块,而不是使用表示法:
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 :: String -> String
String
实际上是[Char]
.
run s = do ln <- lines s ...
简化的东西很多,一个do
块必须在"运行" Monad
.这意味着它"返回"一个类型的值(Monad t) => t a
.由于此函数正在返回[Char]
,因此该do
块将返回[Char]
,这意味着Monad
它[]
(如果您读[a]
为[] a
,则会更清楚).
复制我的另一个答案,
在IO monad的do块上简化了很多事情,每一行都是:
返回"IO a"类型值的东西; 其中"a"类型的值被丢弃(因此"a"通常是"()")
一个< - 表达式,它执行相同的操作,但不是丢弃"a"类型的值,而是给出了< - 左侧的名称 -
一个let,它只是给一个值赋一个名字
在这里,我们不是在IO
Monad上,而是在[]
Monad上.因此,权利的表达<-
必须是一个[a]
.
所以,在do
块的第一行:
ln <- lines s
这里的类型是[[Char]]
,所以类型ln
是[Char]
.
在下一行:
seq <- ln!!0
这里ln!!0
有类型Char
,但由于你在[]
Monad,它期待一些类型的列表.这是导致编译器错误消息的原因.
解决方案是do
使用普通let
块,而不是使用表示法:
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)
我没有编译这个块,但即使它还有其他问题,它应该足以让你重新开始.