У меня есть небольшая программа Haskell, поведение которой должно немного меняться в зависимости от количества предоставленных аргументов. Я не могу решить, как назначить три переменные аккуратным способом, основанным на количестве предоставленных аргументов.Haskell - Назначить переменные с `case` в` do` block
Я хочу использовать что-то вроде выражения 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
как на императивном языке?
Как выполнить эту зависимую переменную?
Возможно, вы могли бы привести небольшой пример сложной логики, для которой кортежей не хватит. – danidiaz
@ danidiaz - Я изо всех сил стараюсь придумать хороший пример. Но предположим, что у меня есть переменные «10», которые я хочу назначить, хотя можно выполнить назначение с помощью кортежей, я чувствую, что это как-то плохая практика и беспорядок, чтобы она распространилась на 10 строк. Мне нравится подход к назначению переменных один за другим, потому что мне легче читать и понимать. – Myridium
В этот момент, возможно, лучшим подходом было бы определить запись с именованными полями для хранения проанализированных опций, а также использовать некоторые из существующих библиотек анализа аргументов, таких как «optparse-generic» или (более сложные и полные -featured) "optparse-applyative". – danidiaz