我在 F# 中有以下代码(来自一本书)
open System.Collections.Generic
type Table<'T, 'U> =
abstract Item : 'T -> 'U with get
abstract Discard : unit -> unit
let memoizeAndPermitDiscard f =
let lookasideTable = new Dictionary<_, _>(HashIdentity.Structural)
{new Table<'T, 'U> with
member t.Item
with get(n) =
if lookasideTable.ContainsKey(n) then
lookasideTable.[n]
else
let res = f n
lookasideTable.Add(n, res)
res
member t.Discard() =
lookasideTable.Clear()}
let rec fibFast =
memoizeAndPermitDiscard (fun n ->
printfn "computing fibFast %d" n
if n <= 2 then 1 else fibFast.[n - 1] + fibFast.[n - 2])
我们可以看到抽象类型 Table 在函数 memoizeAndPermitDiscard
中实现了它。 Haskell 也能做到吗?
最佳答案
提前致歉:我不是 F# 专家,所以我可能误读了 F# 代码。但是如果我没看错的话,翻译成 Haskell 是相当简单的:
data Table t u = Table { get :: t -> IO u, discard :: IO () }
memoize :: Hashable t => (t -> u) -> IO (Table t u)
memoize f = do
tbl <- newHashTable
return Table
{ get = \t -> do
result <- lookupHashTable t tbl
case result of
Nothing -> let u = f t in writeHashTable t u tbl >> return u
Just u -> return u
, discard = clearHashTable tbl
}
我假设这里有一些合适的哈希表实现,它提供了 newHashTable
、lookupHashTable
、writeHashTable
和 clearHashTable
。我认为,实现这些(或建议提供它们的图书馆)有点偏离问题的重点。
关于haskell - Haskell 是否支持类型类的匿名实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46182346/