簡體   English   中英

未解決的頂級重載

[英]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被約束為返回相同的類型,所以編譯器會試圖找到同時滿足sqrtFloating約束和modIntegral約束的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM