在haskell中声明函数中的字典

时间:2014-04-28 04:32:20

标签: haskell

我正在编写代码

import Data.Map

main = print $ scores ["APPLE","bbd","cat"]
score :: String -> Int
score = sum . map latterScore

scores :: [String] -> [Int]
scores arrayOfStrings = [ score word | word <- arrayOfStrings]

myLookup :: Char -> Int
myLookup inputChar = x <- Data.Map.fromList([("A",1), ("B",3), ("C", 3), ("E", 1), ("D", 2), ("G", 2), ("F", 4), ("I", 1), ("H", 4), ("K", 5), ("J", 8), ("M", 3), ("L", 1), ("O", 1), ("N", 1), ("Q", 10), ("P", 3), ("S", 1), ("R", 1), ("U", 1), ("T", 1), ("W", 4), ("V", 4), ("Y", 4), ("X", 8), ("Z", 10)])
        case Data.Map.lookup inputChar x of Nothing -> undefined
                                        (Just v) -> v

但是这显示错误,因为输入&#39;&lt; - &#39;在第1行,即字典 我们可以在不使用案例的情况下编写此代码吗?

2 个答案:

答案 0 :(得分:7)

<-用于列表推导和do表示法,而您两者都没有使用。您可能打算使用let

myLookup inputChar = let x = ... in case Data.Map.lookup inputChar x of ...

其他选项将使用where

myLookup inputChar = case Data.Map.lookup inputChar x of ...
  where x = ...

或者只是引入模块级绑定:

x = ...

myLookup inputChar = case Data.Map.lookup inputChar x of ...

至于删除case,您可以在导入Data.Maybe后使用fromJust

fromJust $ Data.Map.lookup inputChar x

哎呀,你甚至可以将fromList权利嵌入其中:

fromJust $ Data.Map.lookup inputChar $ Data.Map.fromList ...

答案 1 :(得分:1)

如果您不喜欢案例表达,可以使用maybe中定义的具有以下类型的Data.Maybe

maybe :: b -> (a -> b) -> Maybe a -> b

通过分析类型签名,您可以猜出它的作用。请注意,类型b是最终输出的类型。

  1. 第一个参数是我们传递Nothing作为输入时返回的“默认”值。
  2. 第二个参数是输入为x时应用于Just x的函数。
  3. 第三个参数是输入本身。
  4. 让我们试一试!

    > import Data.Maybe
    > maybe 7 (+1) Nothing
    7
    > maybe 7 (+1) (Just 1)
    2
    

    这比使用fromJust更加安全,Nothing会在> fromJust Nothing *** Exception: Maybe.fromJust: Nothing 传递给它时中断。

    maybe 0 id (Data.Map.lookup inputChar x)
    

    您的案例表达可以写成:

    0

    请注意使用undefined代替maybe。零是加法的中性元素,不会改变总和的结果。这样,您就拥有了一个完全安全的功能,并且不会因任何输入而失败。

    根据评论中的建议,当您传递给id的函数为fromMaybe时,最好使用-- fromMaybe :: a -> Maybe a -> a fromMaybe 0 (Data.Map.lookup inputChar x)

    import qualified Data.Map as M
    import Data.Maybe
    
    main = print $ map score ["APPLE", "bbd", "cat"]
    
    score :: String -> Int
    score = sum . map myLookup
    
    myLookup :: Char -> Int
    myLookup inputChar = fromMaybe 0 (M.lookup inputChar dict)
      where dict = M.fromList [('A',1),('B',3),('C',3),('E',1),('D',2),('G',2)
                              ,('F',4),('I',1),('H',4),('K',5),('J',8),('M',3)
                              ,('L',1),('O',1),('N',1),('Q',10),('P',3),('S',1)
                              ,('R',1),('U',1),('T',1),('W',4),('V',4),('Y',4)
                              ,('X',8),('Z',10)
                              ]
    

    这是完整版(我稍微修改了一下):

    {{1}}
相关问题