当前位置:  开发笔记 > 编程语言 > 正文

功能编程新手

如何解决《功能编程新手》经验,为你挑选了1个好方法。

嘿,我是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.



1> CesarB..:

我从编辑窗口复制了代码(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.

推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有