./index.html ../index.html

Haskellを電卓として使う

関数型言語に慣れるために、Haskellを電卓用途に使ってみたいと思います。(僕が)

Haskellの処理系は、コンパイラであっても対話環境が用意されていたりしますが、Hugsの方がいいでしょうね。 起動速度と、ウィンドウアプリという点の両方で。 …と思ったら、Hugsは英語キーボード前提か、日本語キーボードじゃマイナスが入力できねえっ…今の今まで忘れてた。 しかたないのでGHCの対話環境であるGHCiを使いますか。

追記: 最新版のHugs(といっても更新はだいぶ前だ…)ならマイナスが入力できます。

四則演算

   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.0, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Prelude> 1+1
2
Prelude> 2-1
1
Prelude> 2*3
6
Prelude> 7/3
2.3333333333333335
Prelude>

当たり前。

Prelude> 7 `div` 3
2
Prelude> 7 `mod` 3
1

`で囲む(中置記法であることを明示しなければならない)けれど、単語はPascalと同じ。

Prelude> 2 ^ 10
1024
Prelude> 2 ** 10
1024.0
Prelude> 2 ** (1/2)
1.4142135623730951

^ が右辺が整数、** が右辺が小数。 ^ はBASIC、** はAdaがそれぞれ使ってた記号ですね。

合計

Prelude> foldl (+) 0 [1, 2, 3, 4]
10
Prelude> foldr (+) 0 [1, 2, 3, 4]
10
Prelude> foldl (-) 0 [1, 2, 3, 4]
-10
Prelude> foldr (-) 0 [1, 2, 3, 4]
-2

右から計算するか左から計算するかの違いのようです。 (((0 - 1) - 2) - 3) - 4 = -10 と、1 - (2 - (3 - (4 - 0))) = -2 ですね。

Prelude> foldl (+) 0 [1..10]
55
Prelude> foldl (+) 0 [a | a <- [1..10], a `mod` 2 == 0]
30		

範囲からリストを作成できたり。 後者は、2 + 4 + 6 + 8 + 10 = 30。

追記。これでいいです。

Prelude> sum [1,2,3,4]
10

文字コード

Prelude> fromEnum 'a'
97
Prelude> fromEnum 'A'
65
Prelude> (toEnum :: Int -> Char) 65
'A'

え?こんなの使わない? そうかなあ…よく使うよ僕は…。 なお、GHCは日本語つーか0~255の範囲を超えた文字コードに対応していないので、16ビットなCharも役たたずです。

前の結果を使う

Prelude> 1 * 2
2
Prelude> it * 3
6
Prelude> it * 4
24

これができなきゃ電卓じゃないですね。

メモリ

Prelude> sqrt 2
1.4142135623730951
Prelude> let m = it
Prelude> m * m
2.0000000000000004

束縛をメモリとして使えます。 しかし…√2の自乗程度で誤差がありやがる。 Windowsの電卓なら2になるのに。 調べてみたらExtended(long double)精度なら2になるようです。Doubleじゃ不足。 *1

π,sin,cos

__   __ __  __  ____   ___      _________________________________________
||   || ||  || ||  || ||__      Hugs 98: Based on the Haskell 98 standard
||___|| ||__|| ||__||  __||     Copyright (c) 1994-2002
||---||         ___||           World Wide Web: http://haskell.org/hugs
||   ||                         Report bugs to: hugs-bugs@haskell.org
||   || Version: Nov 2002       _________________________________________

Hugs mode: Restart with command line option +98 for Haskell 98 mode

Reading file "C:\Program Files\Hugs98\lib\Prelude.hs":

Hugs session for:
C:\Program Files\Hugs98\lib\Prelude.hs
Type :? for help
Prelude> pi
3.14159
Prelude> sin pi
-8.74228e-008
Prelude> cos pi
-1.0
Prelude> 4 * (atan 1)
3.14159
Prelude> tan (pi/4)
1.0
Prelude> atan2 1 1
0.785398
Prelude> atan2 1 0
1.5708
Prelude> atan2 0 1
0.0

精度がやや不満。 しかしWinHugs起動が速くていいですね。


*1 C#(.NET)の浮動小数点演算が如何に高速でも、C++/Delphiの代用にはならないと思う瞬間でもあります。 つーか、演算精度を型名にするな。 どうせ浮動小数点なんてDirectXみたいな事情が無ければ一種類しか使わないし、その環境で使える最高精度(IntelならExtended)を"Real"にすりゃいいのに→全ての言語
と書いてはみたものの気になったので実際にC#でやってみたら2になるので、細かく見てみたら表示桁数を減らして(四捨五入して)誤魔化してやがる…。