結城浩のHaskell日記 RSSフィード

2006-06-10

リダクション数を表示する リダクション数を表示する - 結城浩のHaskell日記 を含むブックマーク

nobsunが:set +sという技を。

へえ、と思ってGHCiでやろうとしたら表示が違っていた。

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

Loading package base ... linking ... done.
can't find file `a.hs'
Prelude> :set +s
Prelude> zipWith (+) [1..3] [4..6]
[5,7,9]
(0.02 secs, 0 bytes)

Hugsでした。

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

Haskell 98 mode: Restart with command line option -98 to enable extensions

Type :? for help
Prelude> :set +s
Prelude> zipWith (+) [1..3] [4..6]
[5,7,9]
(191 reductions, 378 cells)

uncurry uncurry - 結城浩のHaskell日記 を含むブックマーク

nobsunがuncurryの話を。

なるほど。

f (x, y) = f' x y

f = uncurry f'

にするのか。

型を調べてみよう。

Prelude> :i uncurry
-- uncurry is a variable
uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c

オープンソースマガジンにnobsunが オープンソースマガジンにnobsunが - 結城浩のHaskell日記 を含むブックマーク

あ、『オープンソースマガジン』2006年7月号にnobsunが登場している(p.100)。「ハッカーがHaskellを使うべきでない10の理由」とのこと。来月はふつけるの青木さんだ。

関数適用の優先順位は高い 関数適用の優先順位は高い - 結城浩のHaskell日記 を含むブックマーク

ふつけるp.158まで来ました。

関数適用の優先順位はどんな演算子の優先順位よりも高い。

a = zipWith (+)
b = [0..4]
c = [1,1,1,1,1]
d = (++)
e = map
f = (6+)
g = [0..4]
z = a b c `d` e f g

実行結果です。

*Main> z
[1,2,3,4,5,6,7,8,9,10]

あ、もしかして`関数`だと演算子の優先順位になるのかな。

追記:nobsunからトラックバックがありました。ありがとうございます。

師匠の記事を題材に、仕様を読みながら整理します。

はじめに+と-の結合性と優先順位を調べておきます。

*Main> :i (+)
-- + is a method in class Num
infixl 6 +
(+) :: forall a. (Num a) => a -> a -> a
*Main> :i (*)
-- * is a method in class Num
infixl 7 *
(*) :: forall a. (Num a) => a -> a -> a
  • + の優先順位は6で左結合
  • * の優先順位は7で左結合

次に、暗黙の `関数` という演算子の優先順位が * よりも高くなることを確認します。理解を確認するため明示的にかっこを付けたものも用意します。

x  =  3 * 2  +  4 * 5
x' = (3 * 2) + (4 * 5)      -- 明示的にかっこを付けた

a = (+)                     -- `a`は暗黙のうちにinfixl 9

y  =  3 *  2 `a` 4   * 5
y' = (3 * (2 `a` 4)) * 5    -- 明示的にかっこを付けた

実行結果です。xとx', yとy'が等しくなることを確認します。

*Main> x
26
*Main> x'
26
*Main> y
90
*Main> y'
90

次に、優先順位を明示的に落としてみます。理解を確認するため明示的にかっこを付けたものも用意します。

p  =   3 + 2   -  4  + 5
p' = ((3 + 2)  -  4) + 5    -- 明示的にかっこを付けた

b = (-)
infixl 0 `b`                -- `b`は最低の優先順位

q  =  3 + 2  `b`  4 + 5
q' = (3 + 2) `b` (4 + 5)    -- 明示的にかっこを付けた

実行結果です。pとp', qとq'が等しくなることを確認します。

*Main> p
6
*Main> p'
6
*Main> q
-4
*Main> q'
-4

追記:「Haskell 98 言語とライブラリ改訂レポート」を読んでいて、HTMLのコメントに原文が埋め込まれているのを知りました。