• 作成:

Haskellで拡張無しでみそスープする

+を実行できるようにするにはNumのインスタンスを作れば良い. みそスープを出力するようにするにはShowを弄れば良い.

しかしデフォルトだと1Integerに型つけられるのでみそスープにはならない.

というわけでどうやってやるのか一瞬わからなくなりました.

Haskellの1 == "x" が違法だなんて誰も言ってない! - QiitaRebindableSyntaxを知りましたが. できれば拡張無しでやりたいですね.

ググったらそういうのはdefault宣言で解決できるようですね.

Haskell 98からあります.

クラス Num における曖昧性はよくあることである。それで、Haskell ではこれを解決するもうひとつの方法を提供する。 default 宣言を使う方法である。

default (t1 , ... , tn)

The Haskell 98 Report: 宣言

main = print $ 1 + 1

data M

instance Show M where
    show _ = "みそスープ"

instance Num M where

default (M)

これで拡張無しでみそスープされます.

と思ったのですが, 元のみそスープはprintではなくてputStrLnですね.

putStrLnの定義を弄れば当然可能でしょうけど, それはレギュレーション違反とします.

putStrLn版は拡張なしでは私の探った限りでは無理そうです.

FlexibleInstancesを使えばputStrLnの定義を変えずにみそスープ可能です.

{-# LANGUAGE FlexibleInstances #-}

main = putStrLn $ 1 + 1

instance Num String where
    _ + _ = "みそスープ"

default (String)

PreludeputStrLnを使わなくて良いというレギュレーションならば拡張も無しに楽にみそスープできます.

import           Prelude (($), (+))
import qualified Prelude as P

main = putStrLn $ 1 + 1

putStrLn _ = P.putStrLn "みそスープ"

と思ったら普通に出来るらしいですね. 知識が足りなかった.

そう言えば元ネタの元ネタのa == 1 && a == 2 && a == 3は拡張無しで楽に可能です.

main = print $ a == 1 && a == 2 && a == 3

data N = N

instance Eq N where
    _ == _ = True

instance Num N where

a = N