Случайная функция в Haskell

В настоящее время я работаю над программой на Haskell (в которой я очень новичок), где мне нужно случайным образом генерировать координаты и использовать их в программе в нескольких местах, однако я не хочу использовать потоки ввода-вывода вокруг всю программу, ни семя. Я видел эту ссылку, где они используют num <- randomIO :: IO Float, однако я продолжаю получать - Couldn't match type `IO' with `[]' Expected type: [Float]. Теоретически мне нужно, чтобы координаты были целыми значениями, поэтому, если есть лучший способ сделать это, это было бы здорово! Полный стек ниже:

Couldn't match type `IO' with `[]'
      Expected type: [Float]
        Actual type: IO Float
    * In a stmt of a 'do' block: y <- randomIO :: IO Float

Пример кода, вызывающего ошибку.

import Data.List
import System.Random

someF :: [[Char]]
someF = do
            ytemp <- randomIO :: IO Float
            []

Вы не можете генерировать случайные числа без протаптывания ни IO (или более специализированной монады), ни семян через программу, по вполне фундаментальным причинам . Одна вещь, которую вы могли бы сделать, это создать бесконечный список случайных чисел заранее, а затем просто использовать его, но на практике это почти не отличается от передачи Gen, за исключением того, что последнее дает вам больше гибкости. Действительно, лучший вариант — использовать монаду. Не обязательно IO, но РВар.

leftaroundabout 22.12.2020 21:01

изучите do-нотацию , если вы не очень хорошо в ней разбираетесь. вы не показываете минимальный воспроизводимый пример здесь, но похоже, что тип вашего do блока [] a, но randomIO :: IO a, а [] не IO. Монада должна быть одинаковой во всем данном do блоке.

Will Ness 22.12.2020 21:07

@WillNess Я добавил минимальный воспроизводимый пример! :)

noo2171k 22.12.2020 21:38

Ваш пример не выдает сообщение об ошибке, подобное тому, которое вы опубликовали.

leftaroundabout 22.12.2020 21:44

@leftaroundabout извините, я обновил пример! :D

noo2171k 22.12.2020 22:05
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
124
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
someF :: [[Char]]
someF = do { ... }

Вот вам блок do, но его нет в действии IO. Это само по себе нормально: do блоки могут быть и других типов, кроме IO, но они должны быть монадического типа. Бывает так, что списки тоже монадические, т.е. компилятор трактует это как

someF :: [] [Char]
someF = do { ... }

(где [] — это не пустой список, а конструктор уровня типа для типов списка).

... Это аналогично

someF :: IO [Char]
someF = do { ... }

в этом случае вы могли бы иметь ytemp <- randomIO в блоке do. И наоборот, в блоке list-monad do у вас может быть, например,

  ytemp <- [1, 2, 5.3] :: [Float]

Вот почему вы получаете это сообщение об ошибке: компилятору требуется что-то типа [...], IOW [] (...), но вместо этого вы даете ему что-то типа IO (...).

Если вам нужно генерировать случайные значения в середине вашего кода, то у вас должна быть подходящая монада (или явно переданные семена).

someF :: IO [[Char]]
someF = do
    ytemp <- randomIO :: IO Float
    return []

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