How does one override show for a newtype?

人走茶凉 提交于 2019-12-04 05:55:29

If you want your own Show instance for A, then just don't derive it and make your own instance:

newtype A = A Int deriving (Eq, Num)

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

Then you can write something like:

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

Of course, if you are defining your own + operator like that, then I don't think your problem requires the newtype A declaration:

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

override the default integer constructors in Haskell so they produce strings

So this is done by defining a Num instance for String. Then (+) can be used as String -> String -> String.

A super quick example:

{-# LANGUAGE TypeSynonymInstances #-}

module A where

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

{-

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

-}

Write a fromIntegral method to get functions from integer literals to strings (e.g. 1 --> "1").

For a more general, more disciplined approach to lifting lists of Num values to Num, see the Hinze approach to streams as Num, http://hackage.haskell.org/package/hinze-streams

Is this what you are trying to do? Create a numeric type so that you can write expressions in Haskell, and then just print them and have them come out as LaTeX math strings?

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

This is complicated by the logic required to handle precedence so that parentheses are inserted correctly. The example prints out:

\[\frac{y}{\frac{1}{2} \left(3 + x + 2 y\right)}\]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!