haskellinstancetypeclasscustom-type

Own Data Types - Conversion between them and native ones


I need to make my own datatype for the representation of natural numbers. The datatypes are (pre) defined as in the following. Furthermore I need to create functions to convert between the native datatype Int and the one(s) given. I managed to convert from Int to the given ones as well as checking if my ZZ datatype is Zero. Although I really cant figure out a way to convert anything but Zero back to Int. Im hoping you guys can give me a hint on how to do this.

data IN_1 = One | Follower IN_1 deriving Show
data ZZ   = Zero | Plus IN_1 | Minus IN_1 deriving Show

type Zed = Int


from_Zed_to_ZZ :: Zed-> ZZ
from_Zed_to_ZZ x 
 | x == 0 = Zero
 | x > 0 = Plus (helper(x))
 | x < 0 = Minus (helper(abs(x)))

helper :: Zed -> IN_1
helper x 
 | x==1 = One
 | otherwise = Follower (helper(x-1))


instance Eq ZZ where
    (==) Zero Zero = True


from_ZZ_to_Zed :: ZZ -> Zed
from_ZZ_to_Zed x |x == Zero = 0

Those are my current test cases: testcases


Solution

  • The way to "unwrap" values wrapped in algebraic data types is by pattern matching. Each function parameter is not just an identifier, but actually a pattern. A pattern may be just an identifier, but it can also be other things. In particular, a pattern may be specified as a data constructor name (such as Plus) followed by one or more other patterns, one for each parameter of that constructor.

    In your case:

    from_ZZ_to_Zed :: ZZ -> Zed
    from_ZZ_to_Zed Zero = 0
    from_ZZ_to_Zed (Plus x) = ...
    from_ZZ_to_Zed (Minus x) = ...
    

    Then, to convert from IN_1 to Zed, use recursion similar to how you have implemented helper:

    unhelper :: IN_1 -> Zed
    unhelper One = 1
    unhelper (Follower x) = unhelper x + 1
    

    And use that for Plus and Minus cases:

    from_ZZ_to_Zed (Plus x) = unhelper x
    from_ZZ_to_Zed (Minus x) = - (unhelper x)