8

Haskell のデフォルトの整数コンストラクターをオーバーライドして、文字列を生成するようにしたいと考えています (主に好奇心のためですが、一時的に LaTeX の \frac{}{} の不便さを解消するための優れた入力代替手段を作成するためです)。

特別なパーサーではなく、言語自体を使用できるようにしたかったのですが、おそらくうまくいかないでしょう...

module Main where

import Prelude hiding ((+))

newtype A = A Int deriving (Eq, Show, Num)
default (A)

(+) :: A -> (A -> String)
(A a) + (A b) = (show a) ++ " + " ++ (show b)

main2 = 3+4

main :: IO ()
main = putStrLn main2

上記の問題は、+ 関数が (A, String) ではなく (A, A) に対してのみ機能することなどです。単純にパターン マッチ "(A a)" を省略し、代わりに "a" と書くと、 show() 関数は "A" を先頭に追加するため、"3" は "3" ではなく "A 3" になります。

A の Show をオーバーライドしたいのですが、かなり頭が痛いようです...

4

3 に答える 3

16

の独自のShowインスタンスが必要な場合はA、それを派生させずに独自のインスタンスを作成してください。

newtype A = A Int deriving (Eq, Num)

instance Show A where
  show (A a) = show a

次に、次のように書くことができます。

(+) :: (Show a, Show b) => a -> b -> String
a + b = show a ++ " + " ++ show b

もちろん、そのように独自の演算子を定義している場合、問題に宣言+は必要ないと思います。newtype A

module Main where

import Prelude hiding ((+))

(+) :: (Show a, Show b) => a -> b -> String
a + b = show a ++ " + " ++ show b

aSum = 3 + 4

main :: IO ()
main = putStrLn aSum
于 2010-04-18T02:34:17.863 に答える
7

Haskellのデフォルトの整数コンストラクターをオーバーライドして、文字列を生成する

したがって、これはStringのNumインスタンスを定義することによって行われます。次に、(+)を文字列->文字列->文字列として使用できます。

超簡単な例:

{-# LANGUAGE TypeSynonymInstances #-}

module A where

instance Num String where (+) = (++)

{-

*A> "hello" + "world"
"helloworld"

-}

fromIntegralメソッドを記述して、整数リテラルから文字列に関数を取得します(例:1-> "1")。

Num値のリストをNumに持ち上げるためのより一般的でより統制のとれたアプローチについては、NumとしてのストリームへのHinzeアプローチ(http://hackage.haskell.org/package/hinze-streams )を参照してください。

于 2010-04-18T01:58:10.037 に答える
5

これはあなたがやろうとしていることですか?Haskell で式を記述できるように数値型を作成し、それらを印刷して LaTeX 数学文字列として出力するだけですか?

module Main where

import Data.Ratio

data LaTeXmath = E Precedence String
    deriving (Eq)

data Precedence = Pterm | Pmul | Padd | Pexp
    deriving (Show, Eq, Ord, Bounded)

expr :: Precedence -> LaTeXmath -> String
expr p (E q s) | p >= q    = s
               | otherwise = "\\left(" ++ s ++ "\\right)"

instance Num LaTeXmath where
    a + b = E Padd (expr Padd a ++ " + " ++ expr Padd b)
    a - b = E Padd (expr Padd a ++ " - " ++ expr Padd b)
    a * b = E Pmul (expr Pmul a ++ " "   ++ expr Pmul b)

    negate a = E Pterm (" -" ++ expr Pterm a)
    abs    a = E Pterm (" |" ++ expr Pexp a ++ "| ")
    signum a = E Pterm (" \\signum (" ++ expr Pexp a ++ ") ")

    fromInteger i = E Pterm (show i)

instance Fractional LaTeXmath where
    a / b = E Pterm ("\\frac{" ++ expr Pexp a ++ "}{" ++ expr Pexp b ++ "}")

    fromRational r = fromInteger num / fromInteger denom
        where num = numerator r
              denom = denominator r

instance Show LaTeXmath where
    show a = "\\[" ++ expr Pexp a ++ "\\]"

sym :: String -> LaTeXmath
sym x = E Pterm x

anExample :: LaTeXmath
anExample = sym "y" / (recip 2 * ( 3 + sym "x" + 2 * sym "y" ) )

main :: IO ()
main = print anExample

これは、括弧が正しく挿入されるように優先順位を処理するために必要なロジックによって複雑になります。例は次のように表示されます。

\[\frac{y}{\frac{1}{2} \left(3 + x + 2 y\right)}\]
于 2010-04-18T06:05:55.643 に答える