gpt4 book ai didi

haskell - haskell ADT 中的类型安全命名字段

转载 作者:行者123 更新时间:2023-12-03 15:05:56 26 4
gpt4 key购买 nike

有一个非常常见的问题,使用 haskell 很容易解决。描述它的代码片段是这样的:

data JobDescription = JobOne { n :: Int }
| JobTwo
| JobThree { n :: Int }
deriving (Show, Eq)

taskOneWorker :: JobDescription -> IO ()
taskOneWorker t = do
putStrLn $ "n: " ++ (show $ n t)

main :: IO ()
main = do
-- this runs ok:
taskOneWorker (JobOne 10)

-- this fails at runtime:
-- taskOneWorker JobTwo

-- this works, but we didn't want it to:
-- taskOneWorker (JobThree 10)

我在这篇文章中描述了这个问题以及可能的解决方案: https://www.fpcomplete.com/user/k_bx/playing-with-datakinds

在这里,在 StackOverflow 上,我想问你 - 这个问题的最佳解决方案是什么,使用哪些工具和文档?

最佳答案

我建议使用 Prism . Prism _JobOne代表Int JobOne 中的值构造函数。在 taskOneWorker我们使用 ^? 进行查找.值 t确实是JobOne构造函数,它的参数在 Just 中返回, 或者不是 JobOne构造函数,我们得到一个 Nothing .

{-# LANGUAGE TemplateHaskell #-}

import Control.Lens

data JobDescription = JobOne { n :: Int }
| JobTwo
| JobThree { n :: Int }
deriving (Show, Eq)
$(makePrisms ''JobDescription)

taskOneWorker :: JobDescription -> IO ()
taskOneWorker t = do
case t ^? _JobOne of
Just n -> putStrLn $ "n: " ++ show n
Nothing -> putStrLn "Not a JobOne"
-- Or 'return ()' if you want to ignore these cases

main :: IO ()
main = do
taskOneWorker (JobOne 10)
taskOneWorker JobTwo
taskOneWorker (JobThree 10)

-- *Main> main
-- n: 10
-- Not a JobOne
-- Not a JobOne

关于haskell - haskell ADT 中的类型安全命名字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26439597/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com