Kev*_*vin 2 dictionary haskell
我是Haskell的新手,我正试图找出一种合理的方式来写地图(准备解决特定的欧拉项目问题)
我希望编写一个用记录填充Map的函数.但我无法让它发挥作用.
let似乎创造的,而不是局部变量
处理smap作为一个全球性的.
必须有一些方法来做到这一点.
我的代码:
import Data.Map (Map)
import qualified Data.Map as Map
smap = Map.fromList [("cocoa",23)]
newdata str n = do
let cpy = Map.insert str n smap
cpy
main = do
let smap = newdata "pennywise" 16
let smap = newdata "krusty" 18
Run Code Online (Sandbox Code Playgroud)
从评论更新:稍后我想计算一个直角三角形等于周长的方式.因此我认为Map是存储分布计数的好方法,例如p10 - > 5种方式,p15 - > 6种方式等.因此,当程序运行时,它会增加已发现的周长值.
您无法Map就地修改(因为Haskell是纯函数式语言),但您可以创建一个几乎等于旧映射的新映射,除了一些已修改的条目.
(不要过分担心效率:反直觉,新版本Map不需要旧版本的完整副本.)
例如,假设我们想要计算字符串中每个字符的频率.让我们编写一个函数,给定一个char c,增加其存储在其中的计数Map
import qualified Data.Map.Strict as M
countChar :: Char -> M.Map Char Int -> M.Map Char Int
countChar c oldMap = newMap
where
newMap = M.insertWith (+) c 1 oldMap
Run Code Online (Sandbox Code Playgroud)
newMap不需要变量,为清楚起见,上面显示了该变量.
该函数insertWith生成新映射,以便在索引处c存储1,如果旧映射中没有值,或者旧映射中1 + x存在先前值x.
要处理完整的字符串,我们使用递归:
countString :: String -> M.Map Char Int
countString "" = M.empty
countString (c:cs) = countChar c (countString cs)
Run Code Online (Sandbox Code Playgroud)
GHCi中的小测试:
> countString "here's an example"
fromList [(' ',2),('\'',1),('a',2),('e',4),('h',1),('l',1),('m',1)
,('n',1),('p',1),('r',1),('s',1),('x',1)]
Run Code Online (Sandbox Code Playgroud)
对于更高级的解决方案countString,如果需要,也可以重写为折叠.使用左严格折叠也可以提高效率.
countString = foldl' (flip countChar) M.empty
Run Code Online (Sandbox Code Playgroud)
人们甚至可以使用州monad来避免绕过Map.如果您正在学习Haskell,请不要担心这一点,首先要学习如何使用递归,模式匹配和Maps 的一些库函数来解决这些类型的任务.
| 归档时间: |
|
| 查看次数: |
1104 次 |
| 最近记录: |