此代码是为了获得2点之间的距离,但我遇到了问题!
@EduardoLeon更新
rango2 :: Int -> [Int] -> [[Int]] -> [Int]
rango2 a b list = if (verif [(list!!a!!0),(list!!a!!1),(list!!a!!2)] (b)) then [1]
else [0]
verif :: [Int] -> [Int] -> Bool
verif a b = if ((distance a b) > a!!2) then True
else False
difference :: Num a => [a] -> [a] -> [a]
difference xs ys = zipWith (-) xs ys
dotProduct :: Num a => [a] -> [a] -> a
dotProduct xs ys = sum $ zipWith (*) xs ys
distance :: Floating a => [a] -> [a] -> a
distance xs ys = sqrt $ dotProduct zs zs
where
zs = difference xs ys
编辑:我无法将Int更改为Float,因为我正在使用列表进行操作 抛出这个错误!
Proyecto.hs:71:18:
No instance for (Floating Int) arising from a use of `distance'
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `(>)', namely `(distance a b)'
In the expression: ((distance a b) > a !! 2)
In the expression:
if ((distance a b) > a !! 2) then True else False
答案 0 :(得分:3)
我正在搜索,我看到我需要将Int更改为Float?
只需将类型签名更改为Float
即可开始工作:
verif :: [Float] -> [Float] -> Bool
您需要更改代码的类型签名,以指示它适用于浮动数据,因为sqrt
函数对此进行操作。一个更通用的解决方案是:
verif :: (Floating a, Ord a) => [a] -> [a] -> Bool
verif a b = if (sqrt((((b!!0)-(a!!0))*((b!!0)-(a!!0)))+(((b!!1)-(a!!1))*((b!!1)-(a!!1)))) < a!!3)
then True
else if (sqrt((((b!!0)-(a!!0))*((b!!0)-(a!!0)))+(((b!!1)-(a!!1))*((b!!1)-(a!!1)))) == a!!3)
then True
else False
Haskell不鼓励使用!!
函数。我建议你以更实用的方式重写函数。
答案 1 :(得分:3)
回答您的具体问题:与更传统的语言不同,Haskell不会自动将整数转换为浮点数。事实上,Haskell中不存在强制转换的概念。您需要使用函数fromIntegral
将整数转换为其他数字类型。您可以在ghci中尝试以下内容:
> let x = 5 :: Integer
> sqrt x
<interactive>:3:1:
No instance for (Floating Integer) arising from a use of `sqrt'
In the expression: sqrt x
In an equation for `it': it = sqrt x
> let y = fromIntegral x :: Double
> sqrt y
2.23606797749979
我还想就您的编码风格提出一些其他建议:
将您的功能分解为更小的功能,完成一件事并做得很好。
函数(!!)
遍历链表以查找n
个元素。这是一个O(n)
操作,如果您打算从同一列表中检索多个元素,则该操作比必要的更昂贵。首选避免多次遍历同一列表的解决方案。
以下是我如何找到两点之间的距离:
difference :: Num a => [a] -> [a] -> [a]
difference xs ys = zipWith (-) xs ys
dotProduct :: Num a => [a] -> [a] -> a
dotProduct xs ys = sum $ zipWith (*) xs ys
distance :: Floating a => [a] -> [a] -> a
distance xs ys = sqrt $ dotProduct zs zs
where
zs = difference xs ys
答案 2 :(得分:0)
我建议你重新审视你的设计。 a
中列表b
和verif
的含义是什么?看起来你找到了两点之间的距离。您可以创建一个类型:
data Point = Point Double Double
和一个功能
distance :: Point -> Point -> Double
使您的代码更具可读性。
这也应该通过使用where
子句或let
绑定来消除两次相同的计算。