Поскольку random
имеет тип (по существу)
random :: Random a => StdGen -> (a, StdGen)
если вы передадите ему StdGen
, который у вас есть, g
, он даст вам значение любого типа, создающего экземпляр типа Random
. Компилятор угадывает, какой тип вам нужен, по тому, как вы его используете. В вашем случае он используется во фрагменте
r < (1/2)
и мы можем изучить типы каждой из этих частей
(<) :: Ord a => a -> a -> Bool
(1/2) :: Fractional a => a
которые вместе означают, что полный тип r
r :: (Random a, Fractional a, Ord a) => a
Этого еще недостаточно для продолжения работы в Haskell, но поскольку это достаточно распространенная ситуация в числовых типах (поскольку числовые литералы разрешаются в неоднозначные типы, а не в конкретные числовые типы), в Haskell существует система «по умолчанию». В частности, действует следующая конфигурация default
(по умолчанию)
default (Integer, Double)
это означает, что если у вас есть неоднозначный тип, ограниченный классами, и либо Integer
, либо Double
могут удовлетворять этим классам, то в этом порядке эти конкретные типы заменяются. В случае r
, Double
создает экземпляры Random
, Ord
и Fractional
поэтому компилятор выбирает r :: Double
.
Наконец, мы рассматриваем экземпляр Random
для Double
, который случайно выбирает Double
значения в интервале (0,1)
. Это означает, что с вероятностью 50 % он будет больше, чем (1/2)
, и поэтому каждый из конструкторов Truth
и Lie
будет выбран с равными шансами.
Наконец, для реальной реализации Random NewBool
, возможно, лучше загрузить экземпляр из очень похожего экземпляра, доступного с Bool
.
instance Random NewBool where
random g = case random g of
(True, g') -> (Truth, g')
(False, g') -> (Lie, g')
хотя это работает только в том случае, если вы не хотите изменять поведение генератора случайных чисел по сравнению с Random Bool
. Однако обратите внимание, что здесь происходит аналогичное разрешение типов, за исключением того, что оно намного упрощено, поскольку я сопоставляю шаблоны True
и False
, что сразу означает, что возвращаемый тип random g
должен быть (Bool, StdGen)
.
person
J. Abrahamson
schedule
20.03.2014
Random Bool
? - person Zeta   schedule 20.03.2014