new*_*cct 18 haskell typeclass
我的意思是定义一个类型类的实例,它应用于函数的本地(let
或where
)范围.更重要的是,我希望在这个实例中的函数是闭包,即能够关闭定义实例的词法范围中的变量(这意味着实例在下次调用它的函数时可能会有不同的工作方式).
我可以为您提供一个简化的用例.假设我有一个基于类型类操作的函数.在这个例子中,我使用平方,它可以在任何类型的实例上运行Num
(是的,平方非常简单,可以很容易地重新实现,但它代表的是一些可能更复杂的东西).我需要能够按原样使用现有功能(无需更改或重新实现).
square :: Num a => a -> a
square x = x * x
Run Code Online (Sandbox Code Playgroud)
现在,假设我希望在模运算中使用此操作,即加法,乘法等等.这对于任何固定的模数基都很容易实现,但是我希望有一些通用的东西,我可以为不同的模数基重复使用.我希望能够定义这样的东西:
newtype ModN = ModN Integer deriving (Eq, Show)
-- computes (x * x) mod n
squareModN ::
squareModN x n =
let instance Num ModN where
ModN x * ModN y = ModN ((x * y) `mod` n) -- modular multiplication
_ + _ = undefined -- the rest are unimplemented for simplicity
negate _ = undefined
abs _ = undefined
signum _ = undefined
fromInteger _ = undefined
in let ModN y = square (ModN x)
in y
Run Code Online (Sandbox Code Playgroud)
关键在于我需要使用from(square
)中的函数,该函数要求其参数是一个类型,它是某个类型类的实例.我定义了一个新类型并使其成为一个实例Num
; 但是,为了正确执行模运算,它取决于模数基数n
,由于此函数的通用设计,模数基数可能会因调用而改变.我希望将实例函数定义为一次性"回调"(如果你愿意),以便square
函数定制它此次执行操作的方式(并且只是这次).
一种解决方案可能是将"闭包变量"直接集成到数据类型本身(即ModN (x, n)
表示它所属的数字和基数),操作只能从参数中提取此信息.但是,这有几个问题:1)对于多参数函数(例如(*)
),它需要在运行时检查这些信息是否匹配,这是丑陋的; 2)实例可能包含0参数"值",我可能希望依赖于闭包变量,但由于它们不包含参数,因此无法从参数中提取它们.
归档时间: |
|
查看次数: |
1048 次 |
最近记录: |