2008-11-14 107 views
3

嗨,我真的是Haskell的新手,並且一生都在使用更經典的編程語言。我不知道這裏發生了什麼。我試圖做一個非常簡單的Viterbi算法實現,但只有兩個州(誠實和不誠實的賭場)函數式編程新手

我有一個問題,我想解決我的數組,但我不認爲我得到類型正確。每當我嘗試解決它時,我或者正在創建一個新陣列 - 同樣愚蠢。尤其要注意myArray,teix和dynamicProgram,請閱讀。漂亮,漂亮,請

 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 | [email protected]@y == (1 @@ y-1)*(em (s!!y) em1)*(trans 1 x t1 t2) = '1' : traceback s 1 (y-1) em1 em2 t1 t2 
          | [email protected]@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 ([email protected]@end) ([email protected]@end) == [email protected]@end = 1 
     | maximum ([email protected]@end) ([email protected]@end) == [email protected]@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 

回答

11

我從編輯窗口中複製的代碼(東西計算器的解析器吃的部分代碼),並試圖在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) 

這有兩個誤區:一個編譯器抱怨是一個優先問題,因爲編譯器加括號readly節目,並可以很容易地通過正確的應用程序是固定的括號中的任何一個或運算符。另一個錯誤,你在修復這個錯誤後會發現,你不能連接一個字符串和一個數字;你必須將數字轉換爲一個字符串。

這完全沒有看着算法甚至大部分代碼,只是看着編譯器的錯誤。如果你想有一個二維數組,例如,第一個錯誤正確的表達應該是:

listArray ((startIndex, startIndex), (endIndex, endIndex)) values 

現在,這兩個邊界是元組,其類型爲Array (Int, Int) Double

+0

非常好做! – Godeke 2008-11-15 00:13:35

1

您可以重寫跨功能是這樣的:

trans :: Int -> Int -> Double -> Double -> Double 
trans 1 1 trans11 trans21 = trans11 
trans 1 2 trans11 trans21 = 1-trans11 
trans 2 1 trans11 trans21 = trans21 
trans _ _ trans11 trans21 = 1-trans21