嘿,我是Haskell的新手,并且一直使用更多经典的编程语言.我不知道这里发生了什么.我正在尝试制作一个非常简单的Viterbi算法实现,但仅限于两个州(诚实和不诚实的赌场)
我有一个问题,我想解决我的数组,但我不认为我的类型是正确的.每当我试图解决它时,我或者我正在制作一个新阵列 - 同样愚蠢.请特别注意myArray,te中缀和dynamicProgram,PLEASE.非常漂亮
Code
import Array
import Char
trans :: Int -> Int -> Double -> Double -> Double
trans from x trans11 trans21 =
if (from == 1) && (x == 1)
then trans11
else if (from == 1) && (x == 2)
then (1-trans11)
else if (from == 2) && (x == 1)
then trans21
else (1-trans21)
em :: Char -> [Double] -> Double
em c list = list!! a
where a = digitToInt c
intToChar :: Int -> Char
intToChar n | n == 1 = '1'
| n == 2 = '2'
casino :: Char -> Int -> Int -> [Double] -> [Double] -> Double -> Double -> Double
casino seqchar 1 y em1 em2 t1 t2= 0.5 * (em seqchar em1)
casino seqchar 2 y em1 em2 t1 t2= 0.5 * (em seqchar em2)
casino seqchar x y em1 em2 t1 t2= maximum[ (1 @@ y-1)*(em seqchar em1)*(trans 1 x t1 t2),(2 @@ y-1)*(em seqchar em2)*(trans 2 x t1 t2) ]
dynamicProgram :: [Char] -> (Char -> Int -> Int -> [Double] -> [Double] -> Double -> Double -> Double) -> [Double] -> [Double] -> Double -> Double -> (Array a b)
dynamicProgram string score list1 list2 trans11 trans21 = myArray 1 len
[score (string!!y) x y list1 list2 trans11 trans21 | x Int -> [Double] -> Array a b
myArray startIndex endIndex values = listArray (startIndex,startIndex) (endIndex,endIndex) values
traceback :: [Char] -> Int -> Int -> [Double] -> [Double] -> Double -> Double -> [Char]
traceback s 1 0 em1 em2 t1 t2 = []
traceback s 2 0 em1 em2 t1 t2 = []
traceback s x y em1 em2 t1 t2 | x@@y == (1 @@ y-1)*(em (s!!y) em1)*(trans 1 x t1 t2) = '1' : traceback s 1 (y-1) em1 em2 t1 t2
| x@@y == (2 @@ y-1)*(em (s!!y) em1)*(trans 2 x t1 t2) = '2' : traceback s 2 (y-1) em1 em2 t1 t2
answer :: [Char] -> [Double] -> [Double] -> Double -> Double -> [Char]
answer string list1 list2 t1 t2 = reverse $ maxC : traceback string max end list1 list2 t1 t2 $ dynamicProgram casino string list1 list2 t1 t2
where
end = (length string) + 1
max | maximum (1@@end) (2@@end) == 1@@end = 1
| maximum (1@@end) (2@@end) == 2@@end = 2
maxC = intToChar max
infix 5 @@
(@@) i j = myArray ! (i, j)
main = do
putStrLn "What is the sequence to test?"
seq state 1 transmission probability?"
trp1 state 2 transmission probability is " ++ (1-trp1)
putStrLn "What is the state 2 -> state 1 transmission probability?"
trp2 state 2 transmission probability is " ++ (1-trp2)
putStrLn "I assume that the prob of starting in either state is 1/2. Go!"
answer seq st1 st2 trp1 trp2
CesarB.. 11
我从编辑窗口复制了代码(stackoverflow的解析器正在吃部分代码)并在ghci上尝试了它,它发现了几个错误.第一个错误是:
foo.hs:34:71: Couldn't match expected type `[e]' against inferred type `(a, b)' In the second argument of `listArray', namely `(endIndex, endIndex)' In the expression: listArray (startIndex, startIndex) (endIndex, endIndex) values In the definition of `myArray': myArray startIndex endIndex values = listArray (startIndex, startIndex) (endIndex, endIndex) values
listArray的类型是:
listArray :: (Ix i) => (i, i) -> [e] -> Array i e -- Defined in GHC.Arr
它需要一个带有下限和上限以及列表的元组.所以,正确的表达可能是:
listArray (startIndex, endIndex) values
并且myArray的类型不是Array a b
,它是Array Int Double
.
第二个错误是:
foo.hs:43:44: Couldn't match expected type `a -> b' against inferred type `[Char]' In the first argument of `($)', namely `maxC : (traceback string max end list1 list2 t1 t2)' In the second argument of `($)', namely `(maxC : (traceback string max end list1 list2 t1 t2)) $ (dynamicProgram casino string list1 list2 t1 t2)' In the expression: reverse $ ((maxC : (traceback string max end list1 list2 t1 t2)) $ (dynamicProgram casino string list1 list2 t1 t2))
$
是关联的,所以最右边的$
是最先看的.它的第一个参数必须是一个函数,它将调用最右边的参数作为参数.但是,这是一个列表.
第三个错误是:
foo.hs:51:11: Couldn't match expected type `Array i e' against inferred type `Int -> Int -> [Double] -> Array a b' In the first argument of `(!)', namely `myArray' In the expression: myArray ! (i, j) In the definition of `@@': @@ i j = myArray ! (i, j)
myArray
不是一个数组; 它是一个函数,它接受三个参数并根据它们构造一个数组.
在这里,你可能习惯了更传统的命令式语言,这可能会使你绊倒.在传统的命令式语言中,拥有一个全局myArray
变量是很自然的,然后您可以从程序的中间访问它.然而,在Haskell中,没有更高级的技巧,当你是初学者时你不应该尝试,"全局"变量更像是一个常数值(在第一次使用时懒得计算,但是你可以根据自己的意愿进行计算由生成可执行文件的编译器).您无法从读取的值作为输入初始化它.
你最好的方法是通过程序传递数组,不幸的是,这需要进行一些更改,否定了@@
运算符的用处.您可以用几种更高级的方式隐藏数组的传递,但在学习时最好更明确一些.
最后一个错误是:
foo.hs:63:4: Couldn't match expected type `[a]' against inferred type `IO ()' In the first argument of `(++)', namely `putStrLn "I assume that the state 1 -> state 2 transmission probability is "' In the expression: (putStrLn "I assume that the state 1 -> state 2 transmission probability is ") ++ (1 - trp1) In a 'do' expression: (putStrLn "I assume that the state 1 -> state 2 transmission probability is ") ++ (1 - trp1)
这有两个错误:编译器抱怨的是一个优先级问题,因为编译器添加的括号可以正确显示,并且可以通过正确应用括号或$
运算符来轻松修复.修复此问题后会发现的另一个错误是您无法连接字符串和数字; 你必须将数字转换为字符串.
这一切都没有看到算法甚至大多数代码,只是查看编译器错误.例如,如果你想要一个二维数组,第一个错误的正确表达式将是:
listArray ((startIndex, startIndex), (endIndex, endIndex)) values
现在两个边界都是元组,它的类型是Array (Int, Int) Double
.
我从编辑窗口复制了代码(stackoverflow的解析器正在吃部分代码)并在ghci上尝试了它,它发现了几个错误.第一个错误是:
foo.hs:34:71: Couldn't match expected type `[e]' against inferred type `(a, b)' In the second argument of `listArray', namely `(endIndex, endIndex)' In the expression: listArray (startIndex, startIndex) (endIndex, endIndex) values In the definition of `myArray': myArray startIndex endIndex values = listArray (startIndex, startIndex) (endIndex, endIndex) values
listArray的类型是:
listArray :: (Ix i) => (i, i) -> [e] -> Array i e -- Defined in GHC.Arr
它需要一个带有下限和上限以及列表的元组.所以,正确的表达可能是:
listArray (startIndex, endIndex) values
并且myArray的类型不是Array a b
,它是Array Int Double
.
第二个错误是:
foo.hs:43:44: Couldn't match expected type `a -> b' against inferred type `[Char]' In the first argument of `($)', namely `maxC : (traceback string max end list1 list2 t1 t2)' In the second argument of `($)', namely `(maxC : (traceback string max end list1 list2 t1 t2)) $ (dynamicProgram casino string list1 list2 t1 t2)' In the expression: reverse $ ((maxC : (traceback string max end list1 list2 t1 t2)) $ (dynamicProgram casino string list1 list2 t1 t2))
$
是关联的,所以最右边的$
是最先看的.它的第一个参数必须是一个函数,它将调用最右边的参数作为参数.但是,这是一个列表.
第三个错误是:
foo.hs:51:11: Couldn't match expected type `Array i e' against inferred type `Int -> Int -> [Double] -> Array a b' In the first argument of `(!)', namely `myArray' In the expression: myArray ! (i, j) In the definition of `@@': @@ i j = myArray ! (i, j)
myArray
不是一个数组; 它是一个函数,它接受三个参数并根据它们构造一个数组.
在这里,你可能习惯了更传统的命令式语言,这可能会使你绊倒.在传统的命令式语言中,拥有一个全局myArray
变量是很自然的,然后您可以从程序的中间访问它.然而,在Haskell中,没有更高级的技巧,当你是初学者时你不应该尝试,"全局"变量更像是一个常数值(在第一次使用时懒得计算,但是你可以根据自己的意愿进行计算由生成可执行文件的编译器).您无法从读取的值作为输入初始化它.
你最好的方法是通过程序传递数组,不幸的是,这需要进行一些更改,否定了@@
运算符的用处.您可以用几种更高级的方式隐藏数组的传递,但在学习时最好更明确一些.
最后一个错误是:
foo.hs:63:4: Couldn't match expected type `[a]' against inferred type `IO ()' In the first argument of `(++)', namely `putStrLn "I assume that the state 1 -> state 2 transmission probability is "' In the expression: (putStrLn "I assume that the state 1 -> state 2 transmission probability is ") ++ (1 - trp1) In a 'do' expression: (putStrLn "I assume that the state 1 -> state 2 transmission probability is ") ++ (1 - trp1)
这有两个错误:编译器抱怨的是一个优先级问题,因为编译器添加的括号可以正确显示,并且可以通过正确应用括号或$
运算符来轻松修复.修复此问题后会发现的另一个错误是您无法连接字符串和数字; 你必须将数字转换为字符串.
这一切都没有看到算法甚至大多数代码,只是查看编译器错误.例如,如果你想要一个二维数组,第一个错误的正确表达式将是:
listArray ((startIndex, startIndex), (endIndex, endIndex)) values
现在两个边界都是元组,它的类型是Array (Int, Int) Double
.