[解決済み] 単純な「平均」関数に苛立つハスケル型
質問
初心者のHaskellで遊んでいるのですが、平均関数を書きたいと思いました。 それは世界で最も簡単なことのように思えました、そうですか?
間違ってますね。
Haskellの型システムは、平均が一般的な数値型で動作することを禁じているようです。積分のリストや分数のリストで動作させることはできますが、両方は無理です。
私が欲しいのは
average :: (Num a, Fractional b) => [a] -> b
average xs = ...
でもしか取れない。
averageInt :: (Integral a, Fractional b) => [a] -> b
averageInt xs = fromIntegral (sum xs) / fromIntegral (length xs)
または
averageFrac :: (Fractional a) => [a] -> a
averageFrac xs = sum xs / fromIntegral (length xs)
で、2番目はうまくいくようです。 変数を渡そうとするまでは
*Main> averageFrac [1,2,3]
2.0
*Main> let x = [1,2,3]
*Main> :t x
x :: [Integer]
*Main> averageFrac x
<interactive>:1:0:
No instance for (Fractional Integer)
arising from a use of `averageFrac ' at <interactive>:1:0-8
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: average x
In the definition of `it': it = averageFrac x
どうやら、Haskellは型にうるさいようです。 それはそれで意味がある。 しかし、それらが両方とも[Num]である可能性があるときは、そうではありません。
RealFracの明らかなアプリケーションを見逃していませんか?
分数の入力を受けたときに窒息しないような、積分を分数に強制する方法はありますか?
を使用する方法はありますか?
Either
と
either
を使用して、任意の種類の数値配列で動作する多相平均関数のようなものを作成することができますか?
Haskellの型システムは、この関数が存在することを完全に禁止していますか?
Haskellを学ぶことは、微積分を学ぶようなものです。 それは本当に複雑で、山のような理論に基づいています。そして、時々、問題は、質問を正しく表現するのに十分な知識さえないほど、気が遠くなるほど複雑です。
(また、脚注: これは宿題の問題に基づいています。しかし、私は、積分と分数の両方の配列で動作するようにする方法があるのではないかと、ひそかに思っています。)
どのように解決するのですか?
根本的に、(/)の種類に制約されているんですね。
(/) :: (Fractional a) => a -> a -> a
ちなみに、Data.List.genericLengthも必要です。
genericLength :: (Num i) => [b] -> i
では、fromIntegralを削除して、より一般的なものにするのはどうでしょう。
import Data.List
average xs = realToFrac (sum xs) / genericLength xs
はReal制約(Int, Integer, Float, Double)のみを持っています...
average :: (Real a, Fractional b) => [a] -> b
これでどんなリアルもどんなフラクショナルになるわけだ。
そして、Haskellの多相な数値リテラルに引っかかるすべての投稿者に注意してください。1は整数ではありません、任意の数です。
Realクラスはたった1つのメソッドを提供します:Numクラスの値を有理数に変える機能です。これはまさに私たちがここで必要としているものです。
そして、このように
Prelude> average ([1 .. 10] :: [Double])
5.5
Prelude> average ([1 .. 10] :: [Int])
5.5
Prelude> average ([1 .. 10] :: [Float])
5.5
Prelude> average ([1 .. 10] :: [Data.Word.Word8])
5.5
関連
-
[解決済み】haskellでリストを逆順にする
-
[解決済み] Haskell - Ord aの型は何を意味するのでしょうか?
-
[解決済み] C++のPOD型とは何ですか?
-
[解決済み] Project Eulerとの速度比較。CとPythonとErlangとHaskellの比較
-
[解決済み] Haskellで大規模設計?[クローズド]
-
[解決済み】Haskellの入門編
-
[解決済み] Rank2Typesの目的は何ですか?
-
[解決済み] Haskellのprintfはどのように動作するのですか?
-
[解決済み] なぜStringを型クラスのインスタンスにできないのですか?
-
[解決済み] foldrはどのように機能するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] なぜHaskellでは整数の割り算ができないのか?
-
[解決済み] Haskellにはなぜ "data "と "newtype "があるのですか?重複] [重複] [重複
-
[解決済み] Haskellにおける "リフティング "とは?
-
[解決済み] リーダーモナドの目的は何ですか?
-
[解決済み] Haskell型とデータコンストラクタ
-
[解決済み] Haskellデータ型のメモリフットプリント
-
[解決済み] 型チェッカーは非常に間違った型置換を許可しているが、プログラムはまだコンパイルできる
-
[解決済み] fixの使い方、効果について教えてください。
-
[解決済み] foldrはどのように機能するのですか?
-
[解決済み] GHCiで関数の型宣言を明示的に行うには?