함수, where 절에 쓰거나 최상위 레벨에 쓸 것인가 (Haskell)

9678 단어 하스켈

개요



아래와 같이 sugar 이외가 sword를 참조하고 있지 않는 경우는,
sword를 최상위 레벨로 정의할지, where 절에 정의할지 선택할 수 있을까 생각합니다.
sugar :: Int -> Char
sugar = chr . sword

sword :: Bool -> Int
sword True  = 1
sword False = 0

or
sugar :: Int -> Char
sugar = chr . sword
  where
    sword :: Bool -> Int
    sword True  = 1
    sword False = 0

어느 것을 좋아합니까?

전치



let/where 절의 구분



나의 다음과 같이 let/where구를 구분하고 있습니다.
  • where
  • 본문의 변수를 참조하지 않고 독립적 인 범위를 갖는 것

  • let
  • 본문에 대한 변수를 참조하는 것


  • 글쎄, 가끔씩 무너지고 있다고 생각하지만!

    여기에 잘못된 예제


    foo :: Int -> Int
    foo x =
      let f :: Int -> Int
          f = (+10)
      in f y
      where
        y = x + 1
    

    f 정도라면 좋지만, 가끔
    「왜 함수 본체(let구)에 포함했다? 왜 함수 본체를 비대화시켰다?」
    라고 생각하는 것이 있습니다.

    y 정도라면 좋지만, 가끔
    "코드를 위에서 아래로 보는 사람의 마음을 생각한 적이 있니? 이봐 어떤 마음으로 where구에 썼어?"
    라고 생각하는 것이 있습니다.

    여기서 올바른 예


    foo :: Int -> Int
    foo x =
      let y = x + 1
      in f y
      where
        f :: Int -> Int
        f = (+10)
    

    인간의 사고법에 상냥한 느낌이 든다.

    주제



    ghci에서는 module 절에서 공개하지는 않지만 최상위 레벨에 정의되어 있다는 것은:load 명령으로 읽을 수있는 것 같습니다.
    (Thanks @igrep , @ 미즈 없음 _ 마나 )

    그래서 저는 디버그상에서의 편리성을 감안해,
    ghci로 읽을 수 있게 해 두고 싶은 것은 톱 레벨에,
    특히 읽고 싶지 않은 것은 where 절에 정의하기로 결정했습니다.

      이하의 예의 lambdaParserapplicationParser 하지만,
    특히 module 밖에는 내고 싶지 않지만 ghci의 :load 그럼 읽고 싶은 것에 해당합니다.
    ( hs 소노다 에서 예제의 발췌.
    자세한 내용은 이 commit
    src/Sonoda/Parser.hs를 참조하십시오.)
    module Sonoda.Parser
      ( exprParser
      ) where
    
    -- | A parser of expressions
    exprParser :: CodeParsing m => m Expr
    exprParser = ExprAtomic <$> atomicValParser
            <<|> lambdaParser
            <<|> ExprSyntax <$> syntaxParser
            <<|> P.parens exprParser
            <<|> applicationParser
    
    -- | A parser for lambda abstractions
    lambdaParser :: CodeParsing m => m Expr
    lambdaParser = do
      P.symbolic '\\'
      n <- identifierParser
      P.colon
      t <- typeParser
      P.dot
      x <- exprParser
      pure $ ExprLambda n t x
    
    -- | A parser for function applications
    applicationParser :: CodeParsing m => m Expr
    applicationParser = do
      applyerOrLonlyIdentifier <- terminatorParser
      maybeApplyee <- const Nothing <$> P.eof <|> Just <$> exprParser
      case maybeApplyee of
        Nothing      -> pure applyerOrLonlyIdentifier
        Just applyee -> pure $ ExprApply applyerOrLonlyIdentifier applyee
      where
        -- A parser for terms that is not an application
        terminatorParser :: CodeParsing m => m Expr
        terminatorParser = ExprAtomic <$> atomicValParser
                      <<|> lambdaParser
                      <<|> ExprSyntax <$> syntaxParser
                      <<|> ExprParens <$> P.parens exprParser
                      <<|> ExprIdent  <$> identifierParser
    

    좋은 웹페이지 즐겨찾기