在函数中使用时,Haskell中的随机返回类型
鉴于: 我想举例说明在函数中使用时,Haskell中的随机返回类型,haskell,random,types,Haskell,Random,Types,鉴于: 我想举例说明Random,所以我从以下内容开始: import System.Random data Rarity = Common | Uncommon | Rare | Legendary deriving (Show, Eq, Ord, Enum, Bounded) 但是,这是在类型构造函数(私有构造函数)上操作的,而不是类型,所以我认为这是一种根本错误的方法 经过深思熟虑,最终对我起作用的是: randomRarity :: (RandomGen
Random
,所以我从以下内容开始:
import System.Random
data Rarity = Common | Uncommon | Rare | Legendary
deriving (Show, Eq, Ord, Enum, Bounded)
但是,这是在类型构造函数(私有构造函数)上操作的,而不是类型,所以我认为这是一种根本错误的方法
经过深思熟虑,最终对我起作用的是:
randomRarity :: (RandomGen g) => g -> (Rarity, g)
randomRarity g = case random g of
(r,g') | r < 0.50 -> (Common, g')
| r < 0.75 -> (Uncommon, g')
| r < 0.88 -> (Rare, g')
| otherwise -> (Legendary, g')
randomRarity g@(RandomGen t) = case (random g :: (Float, RandomGen t)) of
...
randomRarity g=案例随机g
(r,g’| r’<0.50->(普通,g’)
|r'<0.75->(不常见,g')
|r'<0.88->(稀有,g')
|否则->(传奇,g')
其中r'=r::Float
这是相当简洁的,但它声明了另一个变量,它的位置远离它想要影响的东西,这意味着当你看到r'
时,你必须做双重判断,然后找出它是什么,然后再回来。最糟糕的是,这让我的好奇心没有得到满足。所以我的问题是:
在这个上下文中,有没有一种方法可以告诉
random g
在我调用它时生成一个Float,或者通过正确声明元组中的第二个类型,或者通过某种方式从g
推断它。或者,如果失败了,有没有一种方法可以约束r
的类型而不声明另一个变量,如r'
?如果您使用GHC,您可以使用-XScopedTypeVariables
(或者将{-#语言范围的TypeVariables#-}
添加到文件的顶部)和代码
randomRarity g = case random g of
(r,g') | r' < 0.50 -> (Common, g')
| r' < 0.75 -> (Uncommon, g')
| r' < 0.88 -> (Rare, g')
| otherwise -> (Legendary, g')
where r' = r :: Float
randomRarity g=案例随机g
(r::Float,g')| r<0.50->(Common,g'))
|r<0.75->(不常见,g')
|r<0.88->(罕见,g')
|否则->(传奇,g')
或者,如果您想使用标准Haskell,您可以使用
randomRarity g = case random g of
(r::Float,g') | r < 0.50 -> (Common, g')
| r < 0.75 -> (Uncommon, g')
| r < 0.88 -> (Rare, g')
| otherwise -> (Legendary, g')
randorarity g=let(r,g')=random g
如果r::的浮点
r | r<0.50->(普通,g')
|r<0.75->(不常见,g')
|r<0.88->(罕见,g')
|否则->(传奇,g')
我认为在这种情况下,最简单的解决方案是显式键入一个您要比较的数字。这将强制执行(
randomRarity g = let (r,g') = random g
in case r :: Float of
r | r < 0.50 -> (Common, g')
| r < 0.75 -> (Uncommon, g')
| r < 0.88 -> (Rare, g')
| otherwise -> (Legendary, g')
randomRarity :: (RandomGen g) => g -> (Rarity, g)
randomRarity g = case random g of
(r,g') | r < (0.50 :: Float) -> (Common, g')
| r < 0.75 -> (Uncommon, g')
| r < 0.88 -> (Rare, g')
| otherwise -> (Legendary, g')
randomRarity g = case first (`asTypeOf` (0 :: Float)) $ random g of
...
first (`asTypeOf` (0 :: Float)) :: (Float, a) -> (Float, a)