簡體   English   中英

在`floor中鍵入默認值。 sqrt`

[英]Type defaults in `floor . sqrt`

使用-Wtype-defaults (附帶-Wall ), floor . sqrt . fromIntegral floor . sqrt . fromIntegral 即使我指定了參數的類型和結果, floor . sqrt . fromIntegral給了我floor . sqrt . fromIntegral警告:

λ> (floor . sqrt . fromIntegral) (10 :: Int) :: Int

<interactive>:356:2-6: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Double’
        (RealFrac a0)
          arising from a use of ‘floor’ at <interactive>:356:2-6
        (Floating a0)
          arising from a use of ‘sqrt’ at <interactive>:356:10-13
        (Num a0)
          arising from a use of ‘fromIntegral’ at <interactive>:356:17-28
    • In the first argument of ‘(.)’, namely ‘floor’
      In the expression: floor . sqrt . fromIntegral
      In the expression: (floor . sqrt . fromIntegral) (10 :: Int) :: Int

<interactive>:356:2-6: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Double’
        (RealFrac a0)
          arising from a use of ‘floor’ at <interactive>:356:2-6
        (Floating a0)
          arising from a use of ‘sqrt’ at <interactive>:356:10-13
        (Num a0)
          arising from a use of ‘fromIntegral’ at <interactive>:356:17-28
    • In the first argument of ‘(.)’, namely ‘floor’
      In the expression: floor . sqrt . fromIntegral
      In the expression: (floor . sqrt . fromIntegral) (10 :: Int) :: Int
3

通過為fromIntegral指定非多態類型,我能夠解決這個問題:

λ> (floor . sqrt . (fromIntegral :: Int -> Double)) (10 :: Int) :: Int
3

以下也有效,但更加繁瑣:

λ> (floor . sqrt . (fromIntegral :: (Integral a) => a -> Double)) (10 :: Int) :: Int
3

我的問題是:

  • 是否有更簡單的方法來處理類型默認警告? (關閉-Wtype-defaults不符合條件。)
  • 這是在Haskell中計算此復合函數(平方根的底面)的值的正確方法嗎? 必須使用fromIntegral並且必須指定中間類型讓我想起了“簡單的事情很難”的諺語。

有三種類型可供選擇(輸入類型,內部使用的中間浮點類型和結果類型),您必須以某種方式告訴編譯器所有這三種類型。 有很多組合來固定它們,但你不能少於三個。

我認為TypeApplications是一種指定這些類型的特別方便的方法。 這是從原始文件開始的一種方法,它有兩個注釋,只添加一個以避免默認:

> :set -XTypeApplications -Wtype-defaults
> (floor . sqrt @Double . fromIntegral) (10 :: Int) :: Int
3

這是另一個可能更符合人體工程學的因素(因為它更准確地說明了括號的位置):

> (floor . sqrt . fromIntegral @Int @Double) 10 :: Int
3

我喜歡你的第三個例子的想法,即修改你的第二個例子,這樣你就不必重復Int ,從而避免潛在的脆弱點。 通過使用特殊的_應用程序,您可以使用類型應用程序以稍微不那么繁瑣的方式實現此目的,這使得編譯器可以使用其中一個類型變量的常用推理過程:

> (floor . sqrt . fromIntegral @_ @Double) (10 :: Int) :: Int
3

這是在Haskell中計算此復合函數(平方根的底面)的值的正確方法嗎? 必須使用fromIntegral並且必須指定中間類型讓我想起了“簡單的事情很難”的諺語。

您最終計算的是整數平方根,因此理想情況下,您希望避免通過sqrt :: Floating a => a -> a來路由計算。 你可能會。 例如,使用integerSquareRoot :: Integral a => a -> aarithmoi庫。

至於你的第一個問題,我第二個Daniel Wagner建議使用TypeApplications擴展來指定中間類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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