前置き
このコードをコンパイルすると、次のようなエラーを吐きます。Wandbox
Haskell
1-- Ex1.hs 2main :: IO() 3main = do 4 let 5 a = 1 :: Int 6 b = 2 :: Int 7 8 print $ (a / b :: Double)
plain
1prog.hs:8:14: error: 2 • Couldn't match expected type ‘Double’ with actual type ‘Int’ 3 • In the second argument of ‘($)’, namely ‘(a / b :: Double)’ 4 In a stmt of a 'do' block: print $ (a / b :: Double) 5 In the expression: 6 do let a = ... 7 b = ... 8 print $ (a / b :: Double) 9 | 108 | print $ (a / b :: Double) 11 | ^^^^^
actual type 'Int' との文言は、 (/) :: Int -> Int -> Int の存在を示唆しているように思えます。
しかし、以下のコードもやはりエラーを吐きます。Wandbox
Haskell
1-- Ex2.hs 2main :: IO() 3main = do 4 let 5 a = 1 :: Int 6 b = 2 :: Int 7 8 print $ (a / b :: Int) -- 単に print $ a / b でも同様のエラーを吐く
plain
1prog.hs:8:14: error: 2 • No instance for (Fractional Int) arising from a use of ‘/’ 3 • In the second argument of ‘($)’, namely ‘(a / b :: Int)’ 4 In a stmt of a 'do' block: print $ (a / b :: Int) 5 In the expression: 6 do let a = ... 7 b = ... 8 print $ (a / b :: Int) 9 | 108 | print $ (a / b :: Int) -- 単に print $ a / b でも同様のエラーを吐く 11 | ^^^^^
エラーの原因が関数の存否に遡り、タイムトラベルを目撃したような気分です。
本題
最大の疑問は、次の二つです。
- 型の一致する関数が無いのであれば、なぜその時点でエラーが出ないのか?
- 定義されていない筈の演算に、なぜ actual type が存在するのか?
また、併せて次の点も気になります。
- 世のHaskellerは 整数÷整数=浮動小数 の計算をどのようにスマートに解決しているのか?
暗黙の型変換が無い以上 fromIntegral に頼るしか無いのでしょうか。
- 整数÷整数=浮動小数 の計算を担う中置関数を自前で用意する場合、慣習的に用いられる命名はあるのか?
とりあえず (*/) :: (Integral a, Integral b) => a -> b -> Double を定義してみましたが、高頻度で用意されそうな関数である以上、慣習的な命名があるのではと考えます。
答えやすい質問だけお答え頂いても結構です。
何か質問に不足がありましたら、どうぞ遠慮無くご指摘下さい。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/21 16:01 編集