How to add fields that only cache something to ADT?

≯℡__Kan透↙ 提交于 2019-12-03 10:17:48

I think all of your goals can be met by using plain old memoization in the function instead of by caching results in the ADT itself. Just a couple weeks ago, I released the stable-memo package, which should help here. Checking over your criteria, I don't think we could do any better than this:

  1. Your data definition doesn't change at all.
  2. Pattern matching doesn't change, either.
  3. Existing code doesn't have to change merely because you write more memoized functions.
    • No existing patterns get broken.
    • No existing memoized functions get broken.

Using it is very simple. Just apply memo to any function you want to memoize, making sure that you use the memoized version of the function everywhere, even in recursive calls. Here's how to write the example you used in your question:

import Data.StableMemo

type VSym = String

data Lambda = Var VSym 
            | App Lambda Lambda
            | Abs VSym Lambda

fv :: Lambda -> Set VSym
fv = memo go
  where
    go (Var v)   = Set.singleton v
    go (App s t) = fv s `Set.union` fv t
    go (Abs v t) = v `Set.delete` fv t
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!