Я пытаюсь создать алгебраический тип данных Die в Haskell, определенный следующим определением:
data Die = Die6 | Die4 | Die20 | Die100
Я определил следующий класс типов
class Roll a where
roll :: (RandomGen g) => a -> Int -> g -> ([Int], g)
rollR :: (RandomGen g) => a -> Int -> Int -> Int -> g -> ([Int], g)
instance Roll Die where
roll Die6 times = generateIntRandomsArray 1 6 times
rollR Die6 times first last = generateIntRandomsArray first last times
{--
roll Die4 times = generateIntRandomsArray 1 4 times (mkStdGen 4)
rollR Die4 times first last = generateIntRandomsArray first last times (mkStdGen 4)
--}
Если я включаю в экземпляр толькоrollDie6 иrollRDie6, все в порядке, но когда я пытаюсь включить Die4, я получаю следующую ошибку:
DieRoller.hs:16:3: error:
Conflicting definitions for ‘roll’
Bound at: DieRoller.hs:16:3-6
DieRoller.hs:18:3-6
|
16 | roll Die6 times = generateIntRandomsArray 1 6 times
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
DieRoller.hs:17:3: error:
Conflicting definitions for ‘rollR’
Bound at: DieRoller.hs:17:3-7
DieRoller.hs:19:3-7
|
17 | rollR Die6 times first last = generateIntRandomsArray first last times
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Я не понимаю сути. Я хочу определить различное поведение в зависимости от того, у кубика 4 или 6 сторон, но, похоже, я что-то упускаю. Вы можете помочь мне ? Спасибо . Чтобы дать вам немного больше информации, у методаgenerateIntRandomsArray есть следующее определение:
generateIntRandomsArray :: (Eq a, Random a, Num a, RandomGen g) => a -> a -> a -> g -> ([a], g)
generateIntRandomsArray start end = generate
where generate 0 generator = ([], generator)
generate numberElements generator =
let (value, newGenerator) = randomR (start,end) generator
(restOfList, finalGenerator) = generate (numberElements-1) newGenerator
in (value:restOfList, finalGenerator)
В Haskell определения функций не могут чередоваться. Проблема в том, что вы частично определяете roll
, затем определяете rollR
, а затем снова возвращаетесь к roll
. Вместо этого сначала сгруппируйте все определения для рулона:
roll Die6 times = ...
roll Die4 times = ...
rollR Die6 times first last = ...
rollR Die4 times first last = ...
Большое спасибо . Это помогло мне решить проблему.
Вы определяете функцию в одном «блоке», а не в нескольких блоках, поэтому:
instance Roll Die where
roll Die4 = generateIntRandomsArray 1 4
roll Die6 = generateIntRandomsArray 1 6
rollR Die4 times first last = generateIntRandomsArray first last times
rollR Die6 times first last = generateIntRandomsArray first last times
в противном случае вы определяете несколько функций с одним и тем же именем, что, конечно, конфликтует.
Я немного скептически отношусь к необходимости использования здесь класса типов. Почему бы вам просто не определить отдельную функцию
roll :: RandomGen g => Die -> Int -> g -> ([Int], g)
?