Idris 中的圆形和 abs 函数
Round and abs function in Idris
我正在尝试编写一个函数
roundedSqrt : Nat -> Nat
roundedSqrt = abs . round . sqrt . fromIntegral
是否有函数
round: Double -> Int
abs : Int -> Nat
或 Idris 中的类似内容?
编辑:
floor : Double -> Int
ceiling : Double -> Int
对于我的用例, 都是 round
的可接受替代方案。
找出您要问的内容的一种方法是使用 Idris REPL。特别是 :search
命令(或其缩写 :s
)。
为了发现我们需要什么才能将 Double -> Double
类型的 sqrt
应用到 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}
不幸的是,它不会编译错误:
Can't cast from Double
to Nat
因为标准库中没有Cast Double Nat
实例(所以cast {to=Nat}
是不合法的)。
作为解决方法,我建议执行从 Double
到 Integer
到 Nat
:
的双重(无双关语意)转换
roundedSqrt : 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}
rounding towards zero, a.k.a. truncation.
顺便说一下,使用 sqrt
可能不是最好的计算方法。当心浮点舍入错误,它们可能会意外地让您得到一个差一的结果。由于您的函数类似于 integer square root,因此最好实现接近于此的功能。
现在介绍 abs
、floor
、ceiling
和 round
函数。
Neg
接口定义 abs
具有以下类型:
abs : Neg ty => ty -> ty
所以你需要做一些简单的类型转换来实现 abs : Int -> Nat
。
标准的 Prelude 也定义了
floor : Double -> Double
ceiling : Double -> Double
所以,再做一点工作就可以将它们重铸成 Double -> Int
。
没有标准的 round
函数,如果您仍然需要它,那么您可以尝试使用 Haskell RealFrac
类型类作为示例来实现它。
我正在尝试编写一个函数
roundedSqrt : Nat -> Nat
roundedSqrt = abs . round . sqrt . fromIntegral
是否有函数
round: Double -> Int
abs : Int -> Nat
或 Idris 中的类似内容?
编辑:
floor : Double -> Int
ceiling : Double -> Int
对于我的用例, 都是 round
的可接受替代方案。
找出您要问的内容的一种方法是使用 Idris REPL。特别是 :search
命令(或其缩写 :s
)。
为了发现我们需要什么才能将 Double -> Double
类型的 sqrt
应用到 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}
不幸的是,它不会编译错误:
Can't cast from
Double
toNat
因为标准库中没有Cast Double Nat
实例(所以cast {to=Nat}
是不合法的)。
作为解决方法,我建议执行从 Double
到 Integer
到 Nat
:
roundedSqrt : 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}
rounding towards zero, a.k.a. truncation.
顺便说一下,使用 sqrt
可能不是最好的计算方法。当心浮点舍入错误,它们可能会意外地让您得到一个差一的结果。由于您的函数类似于 integer square root,因此最好实现接近于此的功能。
现在介绍 abs
、floor
、ceiling
和 round
函数。
Neg
接口定义 abs
具有以下类型:
abs : Neg ty => ty -> ty
所以你需要做一些简单的类型转换来实现 abs : Int -> Nat
。
标准的 Prelude 也定义了
floor : Double -> Double
ceiling : Double -> Double
所以,再做一点工作就可以将它们重铸成 Double -> Int
。
没有标准的 round
函数,如果您仍然需要它,那么您可以尝试使用 Haskell RealFrac
类型类作为示例来实现它。