3

ねえ、私は本当に Haskell に慣れていないので、これまでずっと古典的なプログラミング言語を使ってきました。ここで何が起こっているのかわかりません。非常に単純なビタビ アルゴリズムの実装を作成しようとしていますが、2 つの状態 (正直なカジノと不誠実なカジノ) のみです。

配列に対処したいという問題がありますが、型を正しく取得しているとは思いません。それか、私はそれに対処しようとするたびに新しい配列を作成しています-同様に愚かです。特にmyArray、te infix、およびdynamicProgramを見てください。かなりきれいにしてください

コード


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
4

2 に答える 2

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

2番目のエラーは次のとおりです。

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))

$は右結合であるため、$最初に右端が表示されます。その最初のパラメーターは関数である必要があり、その右端のパラメーターを引数として呼び出します。ただし、ここではリストです。

3番目のエラーは次のとおりです。

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配列ではありません。これは、3つのパラメーターを受け取り、それらに基づいて配列を作成する関数です。

ここでは、おそらく、より伝統的な命令型言語に慣れていることがあなたをつまずかせています。従来の命令型言語で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)

これには2つのエラーがあります。コンパイラが文句を言ったのは、コンパイラが追加した括弧がすぐにわかるように、優先順位の問題であり、括弧または$演算子を正しく適用することで簡単に修正できます。これを修正した後に見つかるもう1つのエラーは、文字列と数値を連結できないことです。数値を文字列に変換する必要があります。

これはすべて、アルゴリズムやほとんどのコードを調べることなく、コンパイラのエラーを調べるだけでした。たとえば、2次元配列が必要な場合、最初のエラーの正しい式は次のようになります。

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

現在、両方の境界はタプルであり、そのタイプはArray (Int, Int) Doubleです。

于 2008-11-15T00:11:13.153 に答える
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
于 2008-11-26T16:03:05.227 に答える