2016-10-31 20 views
0

我想做一个函数worp,返回2个整数列表。如何在Haskell中获得8-x随机值?

其中第一个整数列表是8减去输入列表长度的结果,掷骰子。

而第二个列表是输入列表。

这是我的代码:

import System.Random 

worp :: [Int] -> [[IO Int]] 
worp d = [werpDobbelstenen (8-length d),d] 

werpDobbelstenen :: Int -> [IO Int] 
werpDobbelstenen 0 = [] 
werpDobbelstenen x = randomRIO (1,6):werpDobbelstenen x-1 

即时得到这个错误:

System.IO> :load "X:\\haskell\\dobbel.hs" 
ERROR file:.\dobbel.hs:17 - Instance of Num [IO Int] required for definitio of werpDobbelstenen 
+0

该代码会导致您引用的错误。请修改您的问题以包含完整且准确的错误消息。 – leftaroundabout

+0

旁注:你可以使'werpDobbelstenen'尾递归:) – niceman

+0

顺便问一下,'worp'如何编译? '[werpDobbelstenen(8长d),d]'不是一个同类名单! – niceman

回答

1

首先,我想为简单起见返回IO [Int]值:

import Control.Monad -- replicateM 
import System.Random -- randomRIO 

werpDobbelstenen :: Int -> IO [Int] 
werpDobbelstenen n = replicateM n (randomRIO (1,6)) 

现在,定义worp更简单,因为只需要一个列表Int并返回所需的一对列表。

worp' :: [Int] -> ([Int], [Int]) 
worp' d = (d, map (\x -> x - length d) d) 

最后,你可以简单地映射worp超过werpDobbelstenen结果得到一个IO ([Int], [Int])值。

worp :: Int -> IO ([Int], [Int]) 
worp n = fmap worp' (werpDobbelstenen n) 

后多一点思考,我想这是你想要什么:

import Control.Monad -- replicateM 
import System.Random -- randomRIO 

werpDobbelstenen :: Int -> IO [Int] 
werpDobbelstenen n = replicateM n (randomRIO (1,6)) 

worp' :: [Int] -> IO ([Int], [Int]) 
worp' d = let n = 8 - length d 
      in do d' <- werpDobbelstenen n 
       return (d, d') 

worp :: Int -> IO ([Int], [Int]) 
worp n = werpDobbelstenen n >>= worp' 

>>> worp 6 
([4,1,2,5,6,4],[1,2]) 

在这种情况下,元组的第二个值始终为n >= 8空列表。您可能希望为大于8的值做一些不同的操作。

+0

我不认为我已经回答了您的实际问题;我对'worp'的定义并不真正对应于你想要的那一对列表。然而,如果这有助于你解决自己的问题,我坚持我提出的'werpDobbelstenen'的定义。 – chepner

+0

我喜欢'import Control.Monad - replicateM'中的注释,但是合格的'import Control.Monad(replicateM)'更好。 – Franky

+0

是的,谢谢! :)这正是我想要的,但是你在第7行犯了一个错字,“worp”应该是“worp”“ – ergoforce