- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我玩过 Haskell,但只是玩玩而已。使用真正的不变性让我感到困惑。
具体来说,我有以下功能(现在主要是调试我投入的东西。
type BySize = Map Int [Finfo]
-- ... other stuff ...
-- Walk directories and return map
walkDir :: String -> BySize -> IO ([BySize])
walkDir rootdir bySize = do
let !bySizeHist = [bySize]
pathWalk rootdir (\root dirs files -> do
forM_ files $ (\file -> do
let !latest = head bySizeHist
finfo <- do processPath (joinPath [root, file]) latest
let !new = addBySize (f_size finfo) finfo latest
let latest_size = Map.keys latest
let new_size = Map.keys new
let error = if latest == new
then
"Error, identical maps!"
else
"Update of map is fine" ++ (show latest_size) ++ (show new_size)
putStrLn error
let !bySizeHist = [new] ++ bySizeHist
putStrLn (fname finfo) ))
return bySizeHist
基本上,我的目标是获得一个
Map
具有 key 文件大小和 Finfo 列表(文件信息)
data
结构作为值。我尝试了很多不同的变体,这只是最新的一个不起作用。
addBySize
自己工作。也就是说,给定大小和一个新的 Finfo 对象,它会根据旧的 Map 正确返回一个新的 Map,但是添加了一个新的键,或者现有的键映射到的列表用新的 Finfo 对象扩展。
bySizeHist
失败(我认为是因为超出了循环范围)。因此,虽然我想在每次循环过程中不断回显扩展的键列表,但我得到的是:
% haskell/find-dups haskell
Update of map is fine[][6]
/home/dmertz/git/LanguagePractice/haskell/that
Update of map is fine[][3235]
/home/dmertz/git/LanguagePractice/haskell/sha1sum.hi
Update of map is fine[][8160]
/home/dmertz/git/LanguagePractice/haskell/sha1sum.o
Update of map is fine[][241]
/home/dmertz/git/LanguagePractice/haskell/sha1sum.hs
Update of map is fine[][6]
IE。
latest
从来都不是 map 的最新版本,但我总是添加
new
在每个循环上,但总是到空的 BySize Map。
getAllFiles
在某种程度上,试图排除符号链接(symbolic link)。但我的方法未能排除作为符号链接(symbolic link)的目录。我尝试了一些不起作用的变体。我的版本仅部分有效:
-- Lazily return (normal) files from rootdir
getAllFiles :: FilePath -> IO [FilePath]
getAllFiles root = do
nodes <- pathWalkLazy root
-- get file paths from each node
let files = [dir </> f | (dir, _, files) <- nodes, f <- files ]
normalFiles <- filterM (liftM not . pathIsSymbolicLink) files
return normalFiles
最佳答案
我会让其他人直接回答您的问题,但正确的做法可能是不这样做。你要写的程序是:
getBySize :: FilePath -> IO BySize
getBySize root = do
-- first, get all the files
files <- getAllFiles root
-- convert them all to finfos
finfos <- mapM getFinfo files
-- get a list of size/finfo pairs
let pairs = [(f_size finfo, finfo) | finfo <- finfos]
-- convert it to a map, allowing duplicate keys
return $ fromListWithDuplicates pairs
这是实现目标的合理且实用的方式。您一次获取所有文件名并应用一些功能转换(到 Finfos、成对、到 map )。无需为可变性或状态大惊小怪。
fromListWithDuplicates
有点复杂,但它是标准的。它经常被重写,以至于它或类似的东西应该是
Data.Map
的一部分。 :
fromListWithDuplicates :: Ord k => [(k, v)] -> Map k [v]
fromListWithDuplicates pairs = Map.fromListWith (++) [(k, [v]) | (k, v) <- pairs]
这个想法是它采用键值对列表,将所有值转换为单例列表,然后使用
fromListWith
在重复的情况下,通过将这些单例连接在一起来生成映射。
getFinfo
功能,无论您的
Finfo
是。我使用以下内容进行测试:
data Finfo = Finfo { f_path :: FilePath, f_size :: Int }
getFinfo :: FilePath -> IO Finfo
getFinfo path = do
sz <- getFileSize path
return $ Finfo path (fromIntegral sz)
唯一剩下的功能是
getAllFiles
,它获取所有文件的列表(作为完整路径名,已经加入父目录)。一种写法是使用
pathWalkLazy
来自
System.Directory.PathWalk
:
getAllFiles :: FilePath -> IO [FilePath]
getAllFiles root = do
nodes <- pathWalkLazy root
-- get file paths from each node
let files = [dir </> file | (dir, _, files) <- nodes, file <- files]
return files
一个完整的示例程序。它需要一个参数,即要处理的目录。
import System.Directory
import System.Directory.PathWalk
import System.Environment
import System.FilePath
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
type BySize = Map Int [Finfo]
getBySize :: FilePath -> IO BySize
getBySize root = do
-- first, get all the files
files <- getAllFiles root
-- convert them all to finfos
finfos <- mapM getFinfo files
-- get a list of size/finfo pairs
let pairs = [(f_size finfo, finfo) | finfo <- finfos]
-- convert it to a map, allowing duplicate keys
return $ fromListWithDuplicates pairs
-- this is a little complicated, but standard
fromListWithDuplicates :: Ord k => [(k, v)] -> Map k [v]
fromListWithDuplicates pairs = Map.fromListWith (++) [(k, [v]) | (k, v) <- pairs]
getAllFiles :: FilePath -> IO [FilePath]
getAllFiles root = do
nodes <- pathWalkLazy root
-- get file paths from each node
let files = [dir </> file | (dir, _, files) <- nodes, file <- files]
return files
data Finfo = Finfo { f_path :: FilePath, f_size :: Int }
deriving (Show)
getFinfo :: FilePath -> IO Finfo
getFinfo path = do
sz <- getFileSize path
return $ Finfo path (fromIntegral sz)
main = do
[root] <- getArgs
bs <- getBySize root
print bs
关于haskell - 使用(伪)可变 Map 调用函数(并更改 Map),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68849794/
为了让我的代码几乎完全用 Jquery 编写,我想用 Jquery 重写 AJAX 调用。 这是从网页到 Tomcat servlet 的调用。 我目前情况的类似代码: var http = new
我想使用 JNI 从 Java 调用 C 函数。在 C 函数中,我想创建一个 JVM 并调用一些 Java 对象。当我尝试创建 JVM 时,JNI_CreateJavaVM 返回 -1。 所以,我想知
环顾四周,我发现从 HTML 调用 Javascript 函数的最佳方法是将函数本身放在 HTML 中,而不是外部 Javascript 文件。所以我一直在网上四处寻找,找到了一些简短的教程,我可以根
我有这个组件: import {Component} from 'angular2/core'; import {UserServices} from '../services/UserService
我正在尝试用 C 实现一个简单的 OpenSSL 客户端/服务器模型,并且对 BIO_* 调用的使用感到好奇,与原始 SSL_* 调用相比,它允许一些不错的功能。 我对此比较陌生,所以我可能会完全错误
我正在处理有关异步调用的难题: 一个 JQuery 函数在用户点击时执行,然后调用一个 php 文件来检查用户输入是否与数据库中已有的信息重叠。如果是这样,则应提示用户确认是否要继续或取消,如果他单击
我有以下类(class)。 public Task { public static Task getInstance(String taskName) { return new
嘿,我正在构建一个小游戏,我正在通过制作一个数字 vector 来创建关卡,该数字 vector 通过枚举与 1-4 种颜色相关联。问题是循环(在 Simon::loadChallenge 中)我将颜
我有一个java spring boot api(数据接收器),客户端调用它来保存一些数据。一旦我完成了数据的持久化,我想进行另一个 api 调用(应该处理持久化的数据 - 数据聚合器),它应该自行异
首先,这涉及桌面应用程序而不是 ASP .Net 应用程序。 我已经为我的项目添加了一个 Web 引用,并构建了各种数据对象,例如 PayerInfo、Address 和 CreditCard。但问题
我如何告诉 FAKE 编译 .fs文件使用 fsc ? 解释如何传递参数的奖励积分,如 -a和 -target:dll . 编辑:我应该澄清一下,我正在尝试在没有 MSBuild/xbuild/.sl
我使用下划线模板配置了一个简单的主干模型和 View 。两个单独的 API 使用完全相同的配置。 API 1 按预期工作。 要重现该问题,请注释掉 API 1 的 URL,并取消注释 API 2 的
我不确定什么是更好的做法或更现实的做法。我希望从头开始创建目录系统,但不确定最佳方法是什么。 我想我在需要显示信息时使用对象,例如 info.php?id=100。有这样的代码用于显示 Game.cl
from datetime import timedelta class A: def __abs__(self): return -self class B1(A):
我在操作此生命游戏示例代码中的数组时遇到问题。 情况: “生命游戏”是约翰·康威发明的一种细胞自动化技术。它由一个细胞网格组成,这些细胞可以根据数学规则生存/死亡/繁殖。该网格中的活细胞和死细胞通过
如果我像这样调用 read() 来读取文件: unsigned char buf[512]; memset(buf, 0, sizeof(unsigned char) * 512); int fd;
我用 C 编写了一个简单的服务器,并希望调用它的功能与调用其他 C 守护程序的功能相同(例如使用 ./ftpd start 调用它并使用 ./ftpd stop 关闭该实例)。显然我遇到的问题是我不知
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
我希望能够从 cmd 在我的 Windows 10 计算机上调用 python3。 我已重新安装 Python3.7 以确保选择“添加到路径”选项,但仍无法调用 python3 并使 CMD 启动 P
我是一名优秀的程序员,十分优秀!