从下面复制的这个问题的答案中得到的代码非常好地仅占用O(n)空间来对n包含O(2^n)节点的深度树进行深度优先遍历.这非常好,垃圾收集器似乎在清理已经处理的树上做得很好.
但我的问题是,怎么样?与列表不同,一旦我们处理第一个元素,我们就可以完全忘记它,我们不能在处理第一个叶节点后废弃根节点.我们必须等到树的左半部分被处理(因为最终我们必须从根部向下遍历).此外,由于根节点指向它下面的节点,依此类推,一直到叶子,这似乎意味着在我们开始之前我们无法收集任何树的前半部分在下半部分(因为所有这些节点仍将从仍然活动的根节点开始引用它们).幸运的是情况并非如此,但有人可以解释一下吗?
import Data.List (foldl')
data Tree = Tree Int Tree Tree
tree n = Tree n (tree (2 * n)) (tree (2 * n + 1))
treeOne = tree 1
depthNTree n t = go n t [] where
go 0 (Tree x _ _) = (x:)
go n (Tree _ l r) = go (n - 1) l . go (n - 1) r
main = do
x <- getLine …Run Code Online (Sandbox Code Playgroud) 我有一个带有的表单,target提交后我希望仅将表单替换为目标页面,而不是整个页面。我已经将表单包装在<frame>标签中,但是在表单提交后,整个页面都重新加载了表单提交目标,而不仅是表单本身(包含在框架标签中)。
无论如何要获得表单提交仅替换该框架。理想情况下,浏览器中的URL不会更改。
如何编写forall约束,例如某些类型系列F和G:
forall x y. G (F x y) ~ (x, y)
Run Code Online (Sandbox Code Playgroud)
是否有可能使用Edward A. Kmett Constraints包裹?如果是这样,可以提供一个小例子吗?我认为我需要使用Forall.
GHC assert在优化时重写s id.或者,可以使用编译器标志更改其行为.但是,我注意到同样的情况不会发生trace.是否有一个版本trace刚刚结束,id好像一个标志没有或被设置?
更一般地说,有没有办法根据用于编译调用模块的编译器标志(而不是用于编译自身的标志)来改变函数的行为.很像assert.或者这种GHC魔法是否只会发生assert?
我正在使用模块中的Nat类型GHC.TypeLits,无可否认地说程序员接口应该在一个单独的库中定义.在任何情况下,GHC.TypeLits都有一个KnownNat带有类函数的类,natVal它将编译时Nat转换为运行时Integer.还有一个类型函数(+)可以增加编译时间Nat.
问题在于(KnownNat n1, KnownNat n2),GHC无法得出这一点KnownNat (n1 + n2).
每当我添加类型级别自然时,这都会导致需要添加的约束爆炸.
另一种方法是自己定义自然数字,如下所示:
data Nat = Zero | Succ Nat
Run Code Online (Sandbox Code Playgroud)
或者使用类似自然的库.但似乎傻不使用其内置的GHC纳茨,这也可以让您很好的类型使用文字数字(即0,1),而不必定义:
N0 = Zero
N1 = Succ N0
etc...
Run Code Online (Sandbox Code Playgroud)
围绕这个问题是否存在GHC KnownNat限制在整个地方都需要?或者我应该忽略GHC.TypeLits我的问题的模块?
当然,生成异构列表的笛卡尔积可以在Haskell中以多种方式完成,例如:
[(x,y) | x <- [1,2,3], y <- [4,5,6]]
Run Code Online (Sandbox Code Playgroud)
要么
(,) <$> [1,2,3] <*> [4,5,6]
Run Code Online (Sandbox Code Playgroud)
但我想要的是这样的功能:
heteroCartesian ::
(a1, a2, ... , an) ->
(b1, b2, ... , bn) ->
((a1,b1), (a1,b2), ... , (a1,bn), (a2,b1), (a2,b2), ... , (a2,bn), (an,b1), ... ,(an,b2), ... , (an,bn))
Run Code Online (Sandbox Code Playgroud)
所以我可以这样做:
f (1,'a',True) (2,'b') ==
((1,2),(1,'b'),('a',2),('a','b'),(True,2),(True,'b'))
Run Code Online (Sandbox Code Playgroud)
我不介意我是使用元组还是其他东西,但我需要像上面一样保留类型信息.
我想要这个的原因是创建测试用例.我有一堆说n功能和m价值观.最终我会将一个函数映射到这些函数上,这些函数将它们全部缩减为相同的类型(a Test)但是到目前为止,n*m我想要执行的测试用例有很多不同的类型(实际上并不是那么简单,因为某些函数只能受限制值的子集).
所以很自然地,将这些异构列表用于其他函数是很好的,例如某些类型map.
我已经看过HList,但它在去年还没有更新过,而且我不确定它是否是最合适的工具.
目前,当我想更新我的一个hackage包时,我会经历这个过程.
当然,如果前一步骤成功,我只想做这些步骤.
我认为其他人有类似的工作流程,有什么能做所有这些步骤吗?我可能在脚本中做(1),(3)和(4),虽然(2)我不太确定(也就是检查travis-ci的结果),但这似乎是一个常见的问题我想知道是否有人已经解决了它所以我不重新发明轮子.
我搜索了Hackage,找不到类似下面的东西,但它似乎相当简单和有用.是否有包含各种数据类型的库?
data HList c where
(:-) :: c a => a -> HList c
Nil :: HList c
Run Code Online (Sandbox Code Playgroud)
我找到的所有HLists都可以有任何类型,并且不受约束.
如果没有我会上传我自己的.
我有一个类型T(如果你感兴趣,是我在这里一直在探索的静态指针的包装器),我可以愉快地编写以下操作:
unpointT :: T a -> a
apT :: T (a -> b) -> T a -> T b
bindT :: T a -> (a -> T b) -> T b
Run Code Online (Sandbox Code Playgroud)
问题是,我没有不受限制的pure功能.pure必须受到我的约束,一些约束表明类型是可序列化的,例如Binary.
pureT :: C a => a -> T a
Run Code Online (Sandbox Code Playgroud)
请注意这两个apT和bindT不受限制.
这一切看起来都像monad一样,但唯一的问题是受限制的纯粹.无论如何,也许有一些GADT包装/解包,我可以使用标准Monad层次结构吗?
如果没有,是否有存在的替换层级,即限制pure但保持<*>和>>=无限制?
还要注意,即使不是,也T a可以对某些人有效,例如通过组合和使用.apure (x :: a)T (b -> …
我有一个t支持以下三个操作的类型:
extract :: t a -> a
duplicate :: t a -> t (t a)
(<*>) :: t (a -> b) -> t a -> t b
Run Code Online (Sandbox Code Playgroud)
当然,我也可以写bind:
(>>=) :: f a -> (a -> f b) -> f b
(>>=) x f = f (extract x)
Run Code Online (Sandbox Code Playgroud)
和join:
join :: t (t a) -> t a
join = extract
Run Code Online (Sandbox Code Playgroud)
但我不能写fmap,也不pure
因此,这有点像“单子”,有点像“共鸣”,但是没有fmap。
从技术上讲,我有一个fmap和pure,但它们受到限制。
我查看了各种受约束的仿函数样式的程序包,但它们似乎也都受约束(<*>),但就我而言(<*>),不受约束。 …