Я хочу переопределить целочисленных конструкторов по умолчанию в Haskell, таким образом, они производят строки (главным образом для любопытства, но временно сделать хорошую входную альтернативу для \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, A) вместо (A, Строка), и т.д. Если Вы просто не учитываете соответствие шаблона" (A)" и пишете "a" вместо этого, то шоу () функция предварительно ожидает, таким образом, "3" становится "3" вместо всего "3".
Я хочу переопределить Шоу A, но это, кажется, настоящая головная боль...
Если вам нужен собственный экземпляр 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 Объявление
:
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
Это то, что вы пытаетесь сделать? Создать числовой тип, чтобы вы могли писать выражения в 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)}\]
переопределяют конструкторы целочисленных значений по умолчанию в Haskell, поэтому они производят строки
Таким образом, это делается путем определения экземпляра Num для String. Тогда (+) можно использовать как String -> String -> String.
Супербыстрый пример:
{-# LANGUAGE TypeSynonymInstances #-}
module A where
instance Num String where (+) = (++)
{-
*A> "hello" + "world"
"helloworld"
-}
Напишите метод fromIntegral для получения функций из целочисленных литералов в строки (например, 1 -> «1»).
Для более общего и более дисциплинированного подхода к переносу списков значений Num в Num см. Подход Hinze к потокам как Num, http://hackage.haskell.org/package/hinze-streams