Sample Match Again Num at Haskell

I have a function that takes Numand performs different actions depending on whether it is a float, double or integer. The only way I found this is to use a type class, but that seems very ugly. Is there a way to match with any type of number and therefore do different things, depending on which of the three Num instances it is? Sort of

myFun :: (Num a) => a -> T
myFun n = case n of
  n :: Int -> something for ints
  n :: Float -> something for floats
  n :: Double -> something for doubles

but not

class MyClass a where
  myFun :: (Num a) => a -> T

with copies to Int, Float, Double?

+4
source share
3 answers

Another admittedly not-so-good way to do this:

import Data.Typeable

myFunc :: (Typeable a, Num a, Show a) => a -> String
myFunc x 
    | typeOf x == typeOf (0:: Int) = "Its an Int: " ++ show x
    | typeOf x == typeOf (0:: Float) = "Its a Float: " ++ show x
    | typeOf x == typeOf (0:: Double) = "Its a Double: " ++ show x

, Num a, , . , - - , , myFunc 42 , , Integer, Num a.

, , .

* > myFunc (42:: Int)
" Int: 42"
* > myFunc (42:: Float)
" : 42,0"
* > myFunc (42:: Double)
" : 42,0"
* > myFunc 42
"*** : Main.hs: (11,1) - (14,66): myFunc

+3

:

module Main where

class Num a => Funnable a where
    myFun :: a -> a

instance Funnable Int where
    myFun = id

instance Funnable Float where
    myFun = (+ 2)

instance Funnable Double where
    myFun = (+ 1)

main :: IO ()
main = do
    print $ myFun (1 :: Int)
    print $ myFun (1 :: Float)
    print $ myFun (1 :: Double)

:

$ stack exec example
1
3.0
2.0

. , , Double:

src/Main.hs:14:13: error:
    • No instance for (Funnable Double) arising from a use of ‘myFun’In the second argument of ‘($)’, namely ‘myFun (1 :: Double)’
      In a stmt of a 'do' block: print $ myFun (1 :: Double)
      In the expression: do { print $ myFun (1 :: Double) }
+7

You can simulate something like this:

data MyNum
    = MDouble Double
    | MInt Int
    | MFloat Float
    deriving (Show,Eq,Ord)

handle :: MyNum -> IO ()
handle (MDouble x) = putStrLn "This is double"
handle (MFloat x) = putStrLn "This is float"
handle (MInt x) = putStrLn "This is int"

Infact a similar type of abstraction was used in the bson library for type modeling Value.

+6
source

Source: https://habr.com/ru/post/1657986/


All Articles