Shell 设计帮助:在Haskell中为外壳建模

Shell 设计帮助:在Haskell中为外壳建模,shell,haskell,Shell,Haskell,我正在尝试使用Haskell进行虚拟shell体验。我的意思是,我的意思是创建一个程序,当从终端窗口执行时,它将您放入一个允许您执行熟悉命令子集(例如,cd和mkdir)的环境中 文件系统将是完全虚拟的,因为它不涉及磁盘上的任何内容 我最初的草图(如下)感觉很笨重,事实上,组成一个MWE是一件累赘,我非常不习惯在功能上表示数据结构,我想得到一些关于如何扭转这种体验的建议。任何带有可用源代码的参考程序都会很有帮助,任何提示或思路都会很有帮助 我写了以下内容 导入符合条件的数据。映射为映射 导入符合

我正在尝试使用Haskell进行虚拟shell体验。我的意思是,我的意思是创建一个程序,当从终端窗口执行时,它将您放入一个允许您执行熟悉命令子集(例如,
cd
mkdir
)的环境中

文件系统将是完全虚拟的,因为它不涉及磁盘上的任何内容

我最初的草图(如下)感觉很笨重,事实上,组成一个MWE是一件累赘,我非常不习惯在功能上表示数据结构,我想得到一些关于如何扭转这种体验的建议。任何带有可用源代码的参考程序都会很有帮助,任何提示或思路都会很有帮助

我写了以下内容

导入符合条件的数据。映射为映射
导入符合条件的数据。作为
类型名称=字符串
类型内容=字符串
类型错误=字符串
数据DiskEntry=文件名内容
|目录{name::name
,entries::Map.Map字符串DiskEntry
}派生(显示)
--|“mkdir”函数在给定目录中创建一个新目录
--目录。尝试创建名为“name”的“DiskEntry”
--在给定的“目录”中。如果已存在具有该名称的条目
--存在一个返回的错误。如果该条目不存在
--然后将其添加到目标“DiskEntry”并返回
--作为元组的一部分,其中左侧条目是旧的(已修改的)“DiskEntry”
--正确的条目是新创建的“DiskEntry”。
mkdir::Name->DiskEntry->任一错误(DiskEntry,DiskEntry)
mkdir entryName destination=do
如果Map.member entryName$条目位于目标位置,则执行以下操作
左$“mkdir:无法创建目录”“++entryName++”“:文件存在”
否则就让我
newDirectory=Directory entryName Map.empty
d=addToEntries entryName新建目录目标
在右侧(d,新目录)
addToEntries::Name->DiskEntry->DiskEntry->DiskEntry
addToEntries newEntryName newEntry destination=do
让
updatedEntries=Map.insert newEntryName newEntry(条目目标)
d=目录(名称目的地)更新
在d
ls::DiskEntry->[DiskEntry]
ls currentDirectory=map snd$map.toList$entries currentDirectory
根::DiskEntry
root=目录“/”Map.empty
main::IO()
main=do
--假设我们有几个“任意一个错误(DiskEntry,DiskEntry)”
--我们知道我们有正确的值,所以从
--然后提取元组中的第一个元素,即
--新修改的“根”目录。
让old=fst$eather.rights[mkdir“bin”root]!!0
putStrLn“连接。拿着这个贝壳,祝它能为你服务。”
putStrLn“我不会让你创造任何东西,但是有一个”
putStrLn“目录,\”/\“您当前所在的目录。”
putStrLn“ls`命令应该让您看到还有什么”
putStrLn“我现在就为你做”
putStrLn$show$ls old
以下哪项输出

➜  ls冒险吉特:(大师)✗ ghci main.hs
GHCi,7.10.2版:http://www.haskell.org/ghc/  :? 求救
[1/1]编译Main(Main.hs,已解释)
好的,模块已加载:Main。
*Main>:Main
有联系的。拿着这个贝壳,祝你吃得好。
我不会让你创造任何东西,但是有一个
您当前所在的目录“/”。
'ls'命令应该让您看到还有什么
我现在就帮你
[目录{name=“bin”,entries=fromList[]}]

我对更新目录的方法非常不满,我更希望我的函数能够就地更新引用的目标目录。这是不是可以通过状态单子来实现?哦,我假设代码看起来很可怕,就像在非惯用的Haskell中一样?

你可能想看看Oleg的代码。你可能想使用codereview.stackexchange.com来回答这类问题。听起来这个问题的作者在问如何让代码做一些不同的事情,这对于代码审查来说是离题的。有关代码检查主题的更多详细信息,请参阅。这是一个不适合StackOverflow的广泛问题。除了代码审查网站,如果您将此发布到或@haskell cafe邮件列表,您可能会得到更好的结果和更多的讨论。我不认为这是一个代码审查问题,我认为这更像是“如何在haskell中建模?”。一种常用的方法是定义一个通常以单子形式出现的函数。在这里,您可以使用类似于
StateT DirState(EitherT String IO)
的东西。