2016-04-23 2 views
0

Я определил новый тип типа «PositiveInteger», как показано ниже.newtype: Может кто-нибудь объяснить мне, как работает этот код?

newtype PositiveInteger = PositiveInteger Integer deriving Show 

fromPositiveInteger :: PositiveInteger -> Integer 
fromPositiveInteger (PositiveInteger i) = i 

toPositiveInteger :: Integer -> PositiveInteger 
toPositiveInteger x 
    | (x < 0) = error "Not applicable to negative numbers" 
    | otherwise = PositiveInteger x 

Когда я выполняю инструкцию 'fromPositiveInteger (10)', я получаю следующую ошибку. Это абсолютно нормально.

*Main> fromPositiveInteger (10) 

<interactive>:7:22: 
    No instance for (Num PositiveInteger) arising from the literal ‘10’ 
    In the first argument of ‘fromPositiveInteger’, namely ‘(10)’ 
    In the expression: fromPositiveInteger (10) 
    In an equation for ‘it’: it = fromPositiveInteger (10) 

Предположим, если я обновил свой код, как показано ниже. утверждение «fromPositiveInteger 10» работает без ошибок. Как это могло произойти?

newtype PositiveInteger = PositiveInteger Integer deriving Show 

fromPositiveInteger :: PositiveInteger -> Integer 
fromPositiveInteger (PositiveInteger i) = i 

toPositiveInteger :: Integer -> PositiveInteger 
toPositiveInteger x 
    | (x < 0) = error "Not applicable to negative numbers" 
    | otherwise = PositiveInteger x 

instance Num PositiveInteger where 
    fromInteger   = toPositiveInteger 
    x + y    = toPositiveInteger (fromPositiveInteger x + fromPositiveInteger y) 
    x - y    = let r = fromPositiveInteger x - fromPositiveInteger y in 
          if r < 0 then error "Unnatural subtraction" 
            else toPositiveInteger r 
    x * y    = toPositiveInteger (fromPositiveInteger x * fromPositiveInteger y) 

*Main> fromPositiveInteger (PositiveInteger 10) 
10 
*Main> fromPositiveInteger 10 
10 

ответ

6

Поскольку PositiveInteger теперь экземпляр Num, 10 (которого наиболее общий тип Num a => a) может иметь тип PositiveInteger, что делает его действительным аргументом в пользу fromPositiveInteger.

Смежные вопросы