【发布时间】:2023-04-06 05:48:02
【问题描述】:
我正在学习 Haskell,我决定实现这个简单的算法来完成插入排序算法的一部分:
while j > 0 and A[j-1] > A[j]
swap A[j] and A[j-1]
j ← j - 1
end while
我是这样做的:
miniSort:: (Eq(a), Ord(a)) => Int -> [a] -> [a]
miniSort j list = if (list !! j) < (list !! (j-1)) && j >0
then miniSort (j-1) (swapElements j (j-1) list)
else list
要做到这一点有点困难,但我做到了(我猜)。
在命令式编程语言中查看我可以简单执行的每个步骤
while j > 0 and A[j-1] > A[j]
print("j is $j")
print("swapping $A[j] with $A[j-1]")
swap A[j] and A[j-1]
print("swapped list: $A")
j ← j - 1
end while
print("ended with j $j")
在 Haskell 上,通过 Writer Monad 插入日志功能要困难得多。我什至没有尝试,因为它会一团糟,然后当我想清理日志记录的东西时,它又会变得一团糟。
有没有办法查看 Haskell 中的函数调用分支?
例如:
miniSort 3 [1,2,4,3,7,8,5]
会扩展成这样的:
miniSort 3 [1,2,4,3,7,8,5] = if (3) < 4 && 3 >0
then miniSort (2) [1,2,3,4,7,8,5]
miniSort 2 [1,2,3,4,7,8,5] = if (3) < 2 && 2 >0
else [1,2,3,4,7,8,5]
[1,2,3,4,7,8,5]
【问题讨论】:
-
看看trace
-
一种解决方案(这对于初学者来说可能有点矫枉过正且难以理解,因此请持保留态度)是使您的函数单子但在单子上具有多态性,并将其写入使用辅助
fix函数的“匿名递归”样式。然后,您可以通过调整递归步骤来添加或删除“仪器”。这里有一个例子:stackoverflow.com/questions/41781460/…
标签: haskell functional-programming