Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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中的Bounded typeclass定义具有浮点范围的类型?_Haskell_Types_Typeclass - Fatal编程技术网

如何使用Haskell中的Bounded typeclass定义具有浮点范围的类型?

如何使用Haskell中的Bounded typeclass定义具有浮点范围的类型?,haskell,types,typeclass,Haskell,Types,Typeclass,由于违反了minBound和maxBound,我预计以下代码将失败并出现类型错误。但是,正如您所看到的,它不会显示错误 {-# OPTIONS_GHC -XTypeSynonymInstances #-} module Main where type Probability = Float instance Bounded Probability where minBound = 0.0 maxBound = 1.0 testout :: Float -> Probab

由于违反了minBound和maxBound,我预计以下代码将失败并出现类型错误。但是,正如您所看到的,它不会显示错误

{-# OPTIONS_GHC -XTypeSynonymInstances #-}
module Main where

type Probability = Float
instance Bounded Probability where
    minBound = 0.0
    maxBound = 1.0

testout :: Float -> Probability
testout xx = xx + 1.0

main = do
  putStrLn $ show $ testout 0.5
  putStrLn $ show $ testout (-1.5)
  putStrLn $ show $ testout 1.5
在序曲中我得到了这个

*Main> :type (testout 0.5)
(testout 0.5) :: Probability
在提示下,我得到:

[~/test]$runhaskell demo.hs
1.5
-0.5
2.5

显然,我没有正确地声明Bounded,而且我确信我在语法上做了一些错误的事情。谷歌上没有太多关于有界类型类的简单内容,所以任何帮助都将不胜感激

这不是
Bounded
的目的
Bounded a
仅定义函数
minBound::a
maxBound::a
。它不会引起任何特殊检查或任何事情

可以使用所谓的智能构造函数定义有界类型。即:

module Probability (Probability) where

newtype Probability = P { getP :: Float }
    deriving (Eq,Ord,Show)

mkP :: Float -> Probability
mkP x | 0 <= x && x <= 1 = P x
      | otherwise = error $ show x ++ " is not in [0,1]"

-- after this point, the Probability data constructor is not to be used

instance Num Probability where
    P x + P y = mkP (x + y)
    P x * P y = mkP (x * y)
    fromIntegral = mkP . fromIntegral
    ...
因此,当您提出问题时,您可以获得您希望的内置功能


要进行这种派生,您可能需要语言扩展
{-#语言通用化newtypederiving}

非常有用,非常感谢。一个问题:您使用了一个省略号(“…”)来定义mkP和mkBC与Num类型的现有操作符交互的各种方式。我想这样做的目的是为概率类型的事物定义算术运算符,它们通过mkP不断运行输出以进行边界检查。如果您不知道在哪里查找
Num
方法:概率实际上是一个数字吗?确实,基础表示是,您必须对基础表示进行算术运算,以评估概率表达式的结果。但实际的概率运算将是(con/dis)连接和反转。
newtype BoundCheck a = BC { getBC :: a }
    deriving (Bounded,Eq,Ord,Show)

mkBC :: (Bounded a) => a -> BoundCheck a
mkBC x | minBound <= x && x <= maxBound = BC x
       | otherwise = error "..."

instance (Bounded a) => Num (BoundCheck a) where
    BC x + BC y = mkBC (x + y)
    ...