使用long where语句编码风格不好?

Lan*_*ton 8 random haskell coding-style where

我是Haskell的新手,所以我对编码风格了解不多.我有一个链接很多随机生成器的函数.这种代码是否被认为是错误的风格,其中我在where声明后有~10行?如果是这样,有哪些替代方案?

#!/usr/bin/env runhaskell
{-# LANGUAGE UnicodeSyntax #-}
module Main where

makeDummy :: RandomGen g ? [String] ? FilePath ? g ? (FilePath, g)
makeDummy words root gen0 = (fullPath, gen7)
  where
      (numWordsInTitle, gen1) = randomR (1 :: Int, 4 :: Int) gen0 -- unused
      (title, gen2) = randomChoice words gen1
      (year, gen3) = randomR (1800 :: Int, 2100 :: Int) gen2
      (resNum, gen4) = randomChoice ["1080", "720", "480"] gen3
      (resLetter, gen5) = randomChoice ["P", "p", "i", "I"] gen4
      res = resNum ++ resLetter
      (shuffled, gen6) = shuffle [title, show year, resNum ++ resLetter] gen5
      (fileExt, gen7) = randomChoice [".mkv", ".mp4", ".ogv", ".srt", ""] gen6
      path = (++ fileExt) $ intercalate " " shuffled
      fullPath = root </> path
Run Code Online (Sandbox Code Playgroud)

由于这可能是一个有点主观的主题,请限制答案,以重新实现Haskell社区代码风格规范,而不是个人意见/美学.

我知道使用的可能性getStdRandom,但想在这里使用纯函数,最好.

Ørj*_*sen 9

根据要求,这里是如何以State最直接的方式重写函数.请注意,顶级类型签名未更改.

makeDummy :: RandomGen g ? [String] ? FilePath ? g ? (FilePath, g)
makeDummy words root = runState $ do
    numWordsInTitle <- state $ randomR (1 :: Int, 4 :: Int) -- unused
    title <- state $ randomChoice words
    year <- state $ randomR (1800 :: Int, 2100 :: Int)
    resNum <- state $ randomChoice ["1080", "720", "480"]
    resLetter <- state $ randomChoice ["P", "p", "i", "I"]
    let res = resNum ++ resLetter
    shuffled <- state $ shuffle [title, show year, resNum ++ resLetter]
    fileExt <- state $ randomChoice [".mkv", ".mp4", ".ogv", ".srt", ""]
    let path = (++ fileExt) $ intercalate " " shuffled
    let fullPath = root </> path
    return fullPath
Run Code Online (Sandbox Code Playgroud)

更常见的情况是,state $通过定义实用程序函数(例如randomChoice已经在Statemonad中),可以避免大多数用法.(这或多或少是MonadRandom包的功能的一部分.)


dfe*_*uer 8

对!在这种情况下,状态monad(甚至更具体地说,随机monad)非常方便.这些允许你将所有转换为某种状态的计算链接在一起,在这种情况下是随机种子.例如,参见Control.Monad.State或寻找MonadRandom.

  • @ Langston"State"monad*是纯粹的,它只是一个纯函数的newtype包装器.[`MonadRandom`](https://hackage.haskell.org/package/MonadRandom)可以纯粹使用,也可以根据需要使用`IO`. (6认同)
  • @ Langston`g - >(a,g)`是一种在类型签名中识别的有用模式 - 它应该立即引起"状态".而'State`是纯粹的,正如Ørjan刚才所说的那样. (4认同)