Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不复制Haskell中的代码的情况下创建许多有界类型?_Haskell_Bounded Types - Fatal编程技术网

如何在不复制Haskell中的代码的情况下创建许多有界类型?

如何在不复制Haskell中的代码的情况下创建许多有界类型?,haskell,bounded-types,Haskell,Bounded Types,对于一个项目,我创建了一个基于Int的类型,在我的例子中,每当程序试图使用超出限制[0..127]的值时,它就会抛出一个错误。下面的代码就是这样做的,它对我来说很有用 在Haskell中是否可以创建第二个有界类型,例如[0..255],而不复制此代码 谢谢你的回答 {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Minitel.Type.MNatural (MNat, mnat, fromMNat) where -- | The MNat

对于一个项目,我创建了一个基于Int的类型,在我的例子中,每当程序试图使用超出限制[0..127]的值时,它就会抛出一个错误。下面的代码就是这样做的,它对我来说很有用

在Haskell中是否可以创建第二个有界类型,例如[0..255],而不复制此代码

谢谢你的回答

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Minitel.Type.MNatural (MNat, mnat, fromMNat) where

-- | The MNat type. The constructor is hidden.
newtype MNat = MakeMNat Int deriving (Real, Eq, Ord, Show)

-- | MNat is a bounded type
instance Bounded MNat where
    minBound = MakeMNat 0
    maxBound = MakeMNat 127

-- | Converts an Int into an MNat
mnat :: Int -> MNat
mnat x | loLimit <= x && x <= hiLimit = MakeMNat x
       | otherwise = error "Number out of bounds"
       where loLimit = fromIntegral (minBound :: MNat)
             hiLimit = fromIntegral (maxBound :: MNat)

-- | Converts an MNat into an Int
fromMNat :: MNat -> Int
fromMNat (MakeMNat i) = i

-- | Converts an Int binary function returning Int to a MNat binary function
--   returning an MNat
mfnat :: (Int -> Int) -> (MNat -> MNat)
mfnat f = mnat . f . fromMNat

mfnat2 :: (Int -> Int -> Int) -> (MNat -> MNat -> MNat)
mfnat2 f x y = mnat $ f (fromMNat x) (fromMNat y)

-- | You can do additions, substractions and multiplication with MNat
instance Num MNat where
    fromInteger = mnat . fromIntegral
    (+)         = mfnat2 (+)
    (-)         = mfnat2 (-)
    (*)         = mfnat2 (*)
    abs         = mfnat abs
    signum      = mfnat signum

-- | Allows to use toInteger with MNat
instance Integral MNat where
    quotRem x y = (fromInteger $ quot x' y', fromInteger $ rem x' y')
                  where (x', y') = (toInteger x, toInteger y)
    toInteger   = toInteger . fromMNat

-- | Allows to generate lists
instance Enum MNat where
    toEnum      = mnat
    fromEnum    = fromMNat
注:

性能在这里不是问题
您可以在GHC 7.8中使用类型级别的文字来执行此操作:

{-# LANGUAGE DataKinds, PolyKinds, ScopedTypeVariables #-}
module SO26723035 where

import GHC.TypeLits
import Data.Proxy

newtype MNat (n :: Nat) = MakeMNat Int deriving (Eq, Ord, Show)

instance KnownNat n => Bounded (MNat n) where
  minBound = MakeMNat 0
  maxBound = MakeMNat . fromInteger $ natVal (Proxy :: Proxy n)

可以使用类型同义词修复单个类型。您的其余代码可以使用此多态MNat进行编译,并进行机械更改。您必须在任何地方添加KnownNat上下文,并在mnat中使用ScopedTypeVariables。

您可以在GHC 7.8中使用类型级别的文字:

{-# LANGUAGE DataKinds, PolyKinds, ScopedTypeVariables #-}
module SO26723035 where

import GHC.TypeLits
import Data.Proxy

newtype MNat (n :: Nat) = MakeMNat Int deriving (Eq, Ord, Show)

instance KnownNat n => Bounded (MNat n) where
  minBound = MakeMNat 0
  maxBound = MakeMNat . fromInteger $ natVal (Proxy :: Proxy n)
可以使用类型同义词修复单个类型。您的其余代码可以使用此多态MNat进行编译,并进行机械更改。您必须在任何地方添加KnownNat上下文,并在mnat中使用ScopedTypeVariables