1. ホーム
  2. haskell

[解決済み] Haskellにおける除算

2022-02-27 10:53:28

質問

Haskellでリストの偶数個だけを半分にする関数を作っているのですが、問題が発生しました。コンパイラを実行すると、intの除算はできない、fractional intの型宣言が必要だと文句を言われます。型宣言をfloatに変更してみましたが、別のエラーが発生するだけでした。以下に関数のコードを記載しますが、どのような形であれ、助けを求めています。

halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
                 | otherwise = x/2:halfEvens xs

お読みいただきありがとうございました。

どのように解決するのですか?

使用方法 div 整数の除算を行う。

halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
                 | otherwise = x `div` 2 : halfEvens xs

(/) 関数は,型が Fractional クラスである引数を必要とし,標準的な除算を行う。 そのため div 関数は Integral クラスの引数を必要とし、整数の除算を行います。

より正確には divmod は負の無限大に向かって丸くなる。 その従兄弟たち。 quotrem と同じように動作します。 C言語での整数除算 で、ゼロに向けて丸める。 divmod は通常、モジュール演算を行う場合(例えば、日付から曜日を計算する場合)には正しいのに対して quotrem の方が若干速い(と思う)。

GHCiでちょっと遊んでみる。

> :t div
div :: Integral a => a -> a -> a
> :t (/)
(/) :: Fractional a => a -> a -> a
> 3 / 5
0.6
> 3 `div` 5
0
> (-3) `div` 5
-1
> (-3) `quot` 5
0
> [x `mod` 3 | x <- [-10..10]]
[2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1]
> [x `rem` 3 | x <- [-10..10]]
[-1,0,-2,-1,0,-2,-1,0,-2,-1,0,1,2,0,1,2,0,1,2,0,1]