В настоящее время я работаю над программой на 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
[]
изучите do-нотацию , если вы не очень хорошо в ней разбираетесь. вы не показываете минимальный воспроизводимый пример здесь, но похоже, что тип вашего do
блока [] a
, но randomIO :: IO a
, а []
не IO
. Монада должна быть одинаковой во всем данном do
блоке.
@WillNess Я добавил минимальный воспроизводимый пример! :)
Ваш пример не выдает сообщение об ошибке, подобное тому, которое вы опубликовали.
@leftaroundabout извините, я обновил пример! :D
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 []
Вы не можете генерировать случайные числа без протаптывания ни
IO
(или более специализированной монады), ни семян через программу, по вполне фундаментальным причинам . Одна вещь, которую вы могли бы сделать, это создать бесконечный список случайных чисел заранее, а затем просто использовать его, но на практике это почти не отличается от передачиGen
, за исключением того, что последнее дает вам больше гибкости. Действительно, лучший вариант — использовать монаду. Не обязательноIO
, но РВар.