我有一个小的Haskell程序,其行为需要根据提供的参数数量略有不同。我不知道如何根据提供的参数数量以一种简洁的方式分配三个变量。
我希望在其他编程语言中使用类似case
表达式或等效switch
的内容,但无法解决问题。
这是我当前(错误的)代码,它依赖于Dice.Base
模块生成随机数:
{-# LANGUAGE ScopedTypeVariables #-}
import Dice.Base
import System.Environment
import Data.List
main :: IO()
--Expected argument formats:
--(number of dice, number of faces on each die, number to add to total)
--(number of dice, number of faces on each die)
--(number of faces on a single die)
main = do
args <- getArgs
--Set the number of dice, number of faces on each die,
--and number to add to sum of rolls.
case (length args) of
3 -> let (numDice ::NaturalP) = toNaturalP $ read $ args!!0;
let (numFaces::NaturalP) = toNaturalP $ read $ args!!1;
let (offset ::Integer ) = read $ args!!2;
2 -> let (numDice ::NaturalP) = toNaturalP $ read $ args!!0;
let (numFaces::NaturalP) = toNaturalP $ read $ args!!1;
let (offset ::Integer ) = 0;
1 -> let (numDice ::NaturalP) = 1;
let (numFaces::NaturalP) = toNaturalP $ read $ args!!0;
let (offset ::Integer ) = 0;
-- 'dc' is a structure capturing the Dice Configuration.
let dc = NumSidesPlus numDice numFaces offset
outcomeInteger <- roll dc
putStrLn("Dice configuration: " ++ (show dc))
putStrLn("Outcome: " ++ (show outcomeInteger))
当然,这不起作用,因为case
会产生一个表达;它不是设计用于do
块。
我知道可以let (a,b,c) = case ...
并将这三个值分配为元组,但我认为这是一种解决方法,因为它对于更复杂的项目并没有帮助我。 do
块内的流量控制方法有哪些?在命令式语言中是否有类似于switch
的东西?
如何完成此因变量赋值?
答案 0 :(得分:4)
不是切换列表的长度然后索引,我宁愿直接在列表上进行模式匹配,同时也使用ViewPatterns
:
main :: IO ()
main = do
args <- getArgs
let (arg1,arg2) = case args of
[] -> (1::Int,"default")
[read -> arg1, read -> arg2] -> (arg1,arg2)
print (arg1,arg2)
如果元组不够,因为提取逻辑很复杂,我会定义一个包含可能替代方案的自定义数据类型。
您还可以使用guards和PatternGuards
扩展名对每场比赛施加复杂条件。
答案 1 :(得分:2)
您需要将变量绑定到表达式并让表达式确定值,而不是假设您可以执行某些pathalogical变量声明:
let (numDice,numFaces,offset) =
case (length args) of
3 -> (toNaturalP $ read $ args!!0
,toNaturalP $ read $ args!!1
,read $ args!!2)
2 -> (toNaturalP $ read $ args!!0
,toNaturalP $ read $ args!!1
,0)
1 -> (1
,toNaturalP $ read $ args!!0
,0)