Sud*_*san 6 variables haskell functional-programming immutability binary-search-tree
我是函数式编程的新手。
我面临的挑战是关于二叉搜索树在 Haskell 中如何工作的思维导图。
到目前为止,其他语言的表现都很好。但是我如何在 Haskell 中模仿这样的事情,即
注意:这是不是根本不可能,因为数据结构是不可变的,所以我们根本不能使用根来插入东西。在这种情况下,Haskell 中如何处理上述情况?
实际上,这一切都以相同的方式发生,只不过我们不是改变现有的树变量,而是从中派生出一棵新树,并记住新树而不是旧树。
例如,您描述的过程的 C++ 草图可能如下所示:
int main(void) {
Tree<string> root;
while (true) {
string next;
cin >> next;
if (next == "quit") exit(0);
root.insert(next);
doSomethingWith(root);
}
}
Run Code Online (Sandbox Code Playgroud)
一个变量、一个读取操作以及带有 mutate 步骤的循环。在 haskell 中,我们做同样的事情,但是使用递归进行循环和递归变量而不是改变局部变量。
main = loop Empty
where loop t = do
next <- getLine
when (next /= "quit") $ do
let t' = insert next t
doSomethingWith t'
loop t'
Run Code Online (Sandbox Code Playgroud)
如果您需要doSomethingWith能够“变异”t并读取它,您可以将程序提升到状态:
main = loop Empty
where loop t = do
next <- getLine
when (next /= "quit") $ do
loop (execState doSomethingWith (insert next t))
Run Code Online (Sandbox Code Playgroud)
用 BST 编写一个例子会花费太多时间,但我给你一个使用列表的类似例子。
让我们发明一个updateListN更新列表中第 n 个元素的方法。
updateListN :: Int -> a -> [a] -> [a]
updateListN i n l = take (i - 1) l ++ n : drop i l
Run Code Online (Sandbox Code Playgroud)
现在我们的程序:
list = [1,2,3,4,5,6,7,8,9,10] -- The big data structure we might want to use multiple times
main = do
-- only for shows
print $ updateListN 3 30 list -- [1,2,30,4,5,6,7,8,9,10]
print $ updateListN 8 80 list -- [1,2,3,4,5,6,7,80,9,10]
-- now some illustrative complicated processing
let list' = foldr (\i l -> updateListN i (i*10) l) list list
-- list' = [10,20,30,40,50,60,70,80,90,100]
-- Our crazily complicated illustrative algorithm still needs `list`
print $ zipWith (-) list' list
-- [9,18,27,36,45,54,63,72,81,90]
Run Code Online (Sandbox Code Playgroud)
看看我们如何“更新”列表但它仍然可用?Haskell 中的大多数数据结构都是持久的,因此更新是非破坏性的。只要我们有周围旧数据的参考,我们就可以使用它。
至于你的评论:
我的程序正在尝试以下操作 a) 将列表转换为二叉搜索树 b) 执行一些 I/O 操作 c) 要求用户输入以在创建的二叉搜索树中插入新值 d) 将其插入到已创建的二叉搜索树中列表。这就是该程序想要做的。不知道如何在 Haskell 中完成这件事(或者)我是否陷入了旧的思维模式。欢迎任何想法/提示。
我们可以画出一个程序:
data BST
readInt :: IO Int; readInt = undefined
toBST :: [Int] -> BST; toBST = undefined
printBST :: BST -> IO (); printBST = undefined
loop :: [Int] -> IO ()
loop list = do
int <- readInt
let newList = int : list
let bst = toBST newList
printBST bst
loop newList
main = loop []
Run Code Online (Sandbox Code Playgroud)