Ошибка в вызове Haskell уравнения ожидаемого типа

Я выполняю следующий вызов метода Haskell

rollD6 ::  (RandomGen g, Int a) => Int -> ([a], g)
rollD6 times =  roll Die6 times (mkStdGen 6)

rollD6InRange :: (RandomGen g, Int a) => Int -> Int -> Int -> ([a], g)
rollD6InRange times start end = rollR Die6 times start end (mkStdGen 6)

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
  roll Die4 times = generateIntRandomsArray 1 4 times
  roll Die20 times = generateIntRandomsArray 1 20 times
  roll Die100 times = generateIntRandomsArray 1 100 times

  rollR Die6  times first last = generateIntRandomsArray first last times
  rollR Die4 times first last = generateIntRandomsArray first last times
  rollR Die20 times first last = generateIntRandomsArray first last times
  rollR Die100 times first last = generateIntRandomsArray first last times

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)

и я получаю следующую ошибку

src/Merp/Die/Boundary/RollADie.hs:11:26: error:
    • Expected kind ‘* -> Constraint’, but ‘Int’ has kind ‘*’
    • In the type signature:
        rollD6 :: (RandomGen g, Int a) => Int -> ([a], g)
   |
11 | rollD6 ::  (RandomGen g, Int a) => Int -> ([a], g)
   |                          ^^^^^

src/Merp/Die/Boundary/RollADie.hs:14:32: error:
    • Expected kind ‘* -> Constraint’, but ‘Int’ has kind ‘*’
    • In the type signature:
        rollD6InRange :: (RandomGen g, Int a) =>
                         Int -> Int -> Int -> ([a], g)
    |
 14 | rollD6InRange :: (RandomGen g, Int a) => Int -> Int -> Int -> ([a], g)
    |                                ^^^^^

Я поигрался с параметрами звонка, но так и не смог понять, что происходит. Подскажите, пожалуйста, что там осталось?

Этот API очень странный. Неужели еще есть подобные экземпляры? Если нет, не делайте это классом. Но если это так, я бы, по крайней мере, ожидал, что это будет класс типа с несколькими параметрами или класс со связанным типом для выходных значений; конечно, не все случайные «спецификации» предназначены для производства Int. 1/2

Daniel Wagner 24.05.2024 08:01

Я также ожидал бы, что повторение будет выполняться вне класса; сделать так, чтобы в методах были только вещи, которые различаются между экземплярами. rollRвероятно, вообще не должно существовать; generateIntRandomsArray уже делает то же самое, без странного игнорируемого первого аргумента. Почему gIRA заставляет счетчик повторений иметь тот же тип, что и генерируемый случайный тип? 2/2

Daniel Wagner 24.05.2024 08:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Int не является классом типов, поэтому:

rollD6 :: (RandomGen g, Int a) => Int -> ([a], g)
rollD6 times = roll Die6 times (mkStdGen 6)

не имеет особого смысла: вы заменяете a на Int, поэтому:

rollD6 :: RandomGen g => Int -> ([Int], g)
rollD6 times = roll Die6 times (mkStdGen 6)

То же самое справедливо и для rollD6InRange.

Я бы также посоветовал сохранить тип диапазона и количество элементов отдельно, поэтому:

generateIntRandomsArray :: (Random a, Integral b, RandomGen g) => a -> a -> b -> 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)

это позволяет нам, например, генерировать из последовательности Char, Bool, Float или чего-либо еще, что является экземпляром Random [Hackage], например:

ghci> generateIntRandomsArray 'a' 'z' 10 (mkStdGen 0)
("nlrkwldbji",1695805043 1336516156)

@Yago: Обычно это не то, что вы обычно делаете, но с некоторыми расширениями (например, TypeFamilies) вы можете использовать Int ~ a в качестве ограничения; «оператор» ~ говорит, что a и Int должны быть унифицированы, чтобы функция могла выполнять проверку типа (т. е. он утверждает, что a должно быть Int).

chepner 24.05.2024 00:01

Хороший . Спасибо за помощь . Просто новичок, пытающийся научиться.

Yago 14.06.2024 10:25

Другие вопросы по теме