[英]Unresolved top level overloading
任務是找到所有可以表示為兩個自然數的sqrt之和的二值數。 我試試這個:
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod` 1 == 0, sqrt (y) `mod` 1 == 0]
結果:
未解決的頂級重載綁定:func優秀上下文:(積分b,浮動b)
我怎樣才能解決這個問題?
發生這種情況是因為這兩種類型之間存在沖突:
sqrt :: Floating a => a -> a
mod :: Integral a => a -> a -> a
因為你寫了mod (sqrt x) 1
,並且sqrt
被約束為返回相同的類型,所以編譯器會試圖找到同時滿足sqrt
的Floating
約束和mod
的Integral
約束的x
類型。 base
庫中沒有滿足這兩個約束的類型。
快速解決方法是使用mod' :: Real a => a -> a -> a
:
import Data.Fixed
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod'` 1 == 0, sqrt (y) `mod'` 1 == 0]
但是,從您發布的錯誤來看,您可能沒有使用GHC,而mod'
可能是GHC主義。 在這種情況下,您可以從此處復制定義(以及輔助函數div'
的定義)。
但我建議更復雜的修復。 關鍵的觀察是,如果x = sqrt y
,那么x*x = y
,所以我們可以完全避免調用sqrt
。 我們可以迭代sqrt
,而不是迭代數字並檢查它們是否具有干凈的sqrt
; 他們的方塊肯定會有干凈的方根。 這種重構的簡單應用可能如下所示:
sqrts = takeWhile (\n -> n*n <= 99)
. dropWhile (\n -> n*n < 10)
$ [0..]
func = [x + y | x <- sqrts, y <- sqrts]
當然, func
是一個可怕的名字(它甚至不是一個函數!),而sqrts
是我們自己可以計算的常數,而且它很短,我們應該只是內聯它。 所以我們可能會簡化為:
numberSums = [x + y | x <- [4..9], y <- [4..9]]
在這一點上,我想知道我是否真的想寫這個,更喜歡
numberSums = [8..18]
與前一次迭代不同,它沒有任何重復。 盡管如此,它已經失去了為什么這是一個有趣的常數的所有解釋力,所以你肯定想要一個評論。
-- sums of pairs of numbers, each of whose squares lies in the range [10..99]
numberSums = [8..18]
這將是我的最終版本。
此外,盡管上述定義沒有通過搜索完美正方形的范圍來參數化,但是當作為參數時,可以應用所有提出的重構; 我把這作為一個很好的練習讓讀者檢查他們是否理解了每一個變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.