Haskell 提供了一个方便的函数forever,可以无限地重复单子效果。它可以定义如下:
forever :: Monad m => m a -> m b
forever ma = ma >> forever ma
Run Code Online (Sandbox Code Playgroud)
然而,在标准库中该函数的定义有所不同:
forever :: Monad m => m a -> m b
forever a = let a' = a *> a' in a'
Run Code Online (Sandbox Code Playgroud)
let 绑定用于强制“此处显式共享,因为无论优化如何,它都可以防止空间泄漏”(来自实现的评论)。
您能解释一下为什么第一个定义可能存在空间泄漏吗?
我写了函数来找到最长的公共子序列(LCS).例如,对于两个字符序列BANANA和ATANA,它返回AANA.实现是递归算法的天真低效适应,但它与此问题的目的无关.
def LCS[T](a: Seq[T], b: Seq[T]): Seq[T] = {
if (a.isEmpty || b.isEmpty)
Seq.empty
else if (a.head == b.head)
a.head +: LCS(a.tail, b.tail)
else {
val case1 = LCS(a.tail, b)
val case2 = LCS(a, b.tail)
if (case1.length > case2.length) case1 else case2
}
}
Run Code Online (Sandbox Code Playgroud)
我想以最通用的方式重构此函数.当前实现适用于任何类型的输入序列,但始终返回List [T]类型的集合.我想实现以下行为:
LCS(List('B','A','N','A','N','A'), List('A','T','A','N','A')) -> List('A','A','N','A')
LCS(Vector('B','A','N','A','N','A'), Vector('A','T','A','N','A')) -> Vector('A','A','N','A')
...and so on for all other Seqs...
如果LCS也可以处理String和Array,那将是很棒的:
LCS("BANANA", "ATANA") -> "AANA"
LCS(Array('B','A','N','A','N','A'), Array('A','T','A','N','A')) -> Array('A','A','N','A')
我相信在Scala …
例如,函数length抽象具体的sequence(Foldable),但不抽象具体的整数类型Int:
length :: Foldable t => t a -> Int
Run Code Online (Sandbox Code Playgroud)
拥有以下类型签名会更有用或更方便吗?
length' :: Foldable t, Integral i => t a -> i
Run Code Online (Sandbox Code Playgroud)