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
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)