伊德里斯的圆形和腹肌功能

时间:2016-09-28 06:57:45

标签: idris

我正在尝试编写一个函数

roundedSqrt : Nat -> Nat
roundedSqrt = abs . round . sqrt . fromIntegral

是否有功能

round: Double -> Int
abs : Int -> Nat

或伊德里斯的类似事情?

编辑:

floor : Double -> Int
ceiling : Double -> Int
对于我的用例,

round都是可接受的替代方案。

1 个答案:

答案 0 :(得分:4)

找出问题的一种方法是使用Idris REPL。特别是:search命令(或其缩写:s)。 要了解我们需要将sqrt Double -> Double类型Nat应用于Idris> :s Nat -> Double < Prelude.Cast.cast : Cast from to => from -> to Perform a cast operation. ,我们可能会尝试这样的事情:

cast

使用我们可以编写以下版本的roundedSqrtDoesntCompile : Nat -> Nat roundedSqrtDoesntCompile = cast {to=Nat} . sqrt . cast {to=Double} 函数:

Double

不幸的是,它不会使用错误编译:

  

无法从Nat投射到Cast Double Nat

因为标准库中没有cast {to=Nat}实例(因此Double不合法)。

作为一种解决方法,我建议执行从IntegerNatroundedSqrt : Nat -> Nat roundedSqrt = cast {to=Nat} . cast {to=Integer} . sqrt . cast {to=Double} 的双重(无双关语)演员:

roundedSqrt : Nat -> Nat
roundedSqrt = cast . cast {to=Integer} . sqrt . cast

可以更简洁地写出

cast {to=Integer}

sqrt rounding towards zero,a.k.a。truncation

顺便说一下,使用abs可能不是计算此问题的最佳方法。注意浮点舍入错误,他们可以出乎意料地得到一个一个接一个的结果。由于您的函数类似于integer square root,因此最好实现与此类似的东西。

现在转到floorceilingroundNeg个功能。

abs接口使用以下类型定义abs : Neg ty => ty -> ty

abs : Int -> Nat

因此,您需要进行一些简单的类型转换才能实现floor : Double -> Double ceiling : Double -> Double

标准Prelude还定义了

Double -> Int

因此,只需要做一点工作,就可以将它们重新转换为round

没有标准class MyDict(dict): def __getitem__(self,key): value=dict.__getitem__(self,key) if callable(value): value=value(self) return value mydict=MyDict({'mass':1.0,'volume':0.5}) mydict['density'] = lambda mydict: mydict['mass']/mydict['volume'] print(mydict['density']) 函数,如果您仍然需要它,那么您可以尝试使用Haskell RealFrac类型类作为示例来实现它。