gpt4 book ai didi

haskell - 编写模式同义词来隐藏构造函数

转载 作者:行者123 更新时间:2023-12-02 18:45:14 25 4
gpt4 key购买 nike

考虑以下因素:

module MyModule (
A(FortyTwo), -- Note we don't expose PrivateA
B(P) -- Nor PrivateB
) where

pattern FortyTwo = A 42

newtype A = PrivateA Int
data B = PrivateB Int Int

pattern P :: Int -> A -> B

我如何编写模式P

基本上我可以说:

f :: B -> String
f (P 2 FortyTwo) = "The meaning of life"

也就是说,能够进行模式匹配,而无需直接在定义它们的模块外部引用私有(private)构造函数 PrivateAPrivateB

最佳答案

首先,请记住 newtype 只能与具有单个参数的数据构造函数一起使用,因此您的 A 可以是 newtypeB 不能。

data B = PrivateB Int Int

现在,您用于 FortyTwo 的模式语法称为隐式双向。也就是说,

pattern FortyTwo :: A
pattern FortyTwo = PrivateA 42

我们使用=并真正表示平等。它说“我可以使用 FortyTwo 构造一个 A,如果我有一个 A,我可以使用 FortyTwo > 进行模式匹配”。这是最简单的形式,在参数定向良好的“简单”情况下非常有用。

但现实世界并不那么简单。所以GHC为我们提供了一个extended syntax称为显式双向模式。简而言之,我们可以明确指定我们希望表达式在模式上下文中的行为方式以及我们希望它在表达式上下文中的行为方式。编译器不会(也不能)检查这两个表达式作为一对是否具有内聚意义,因此我们可以使用它来做一些像这样的废话

pattern Nonsense :: Int -> Int
pattern Nonsense n <- n where
Nonsense _ = 42

这定义了 Nonsense,使得 let Nonsense x = Nonsense 0 in x 返回 42

但是您的用例听起来完全合理,因此我们可以使用明确的双向模式来定义它。

我们还需要完成一个小部分来完成这个任务,这就是 view patterns 。 View 模式是一种模式(因此,我们在模式匹配中使用它),它实际上只是一个变相的函数调用。简而言之,以下内容大致相同

let y = f x in y
let (f -> y) = x in y

它实际上只是将函数调用移至等号的另一侧,这在某些情况下可以方便地编写简洁的代码。在定义模式同义词时它也很有用。

pattern P :: Int -> A -> B
pattern P n a <- PrivateB n (PrivateA -> a) where
P n (PrivateA a) = PrivateB n a

第一行当然是类型声明。第二行表示“当我看到 P n a 形式的模式时,假装它显示 PrivateB n (PrivateA -> a)”。最后一行表示“当我看到一个表示 P n (PrivateA a) 的表达式时,构造一个 PrivateB n a”。这定义了一个 Haskell 函数(并且该函数是详尽的,因为 A 只有一个构造函数,并且我们已经处理了它)。

完整的可运行示例:

{-# LANGUAGE PatternSynonyms, ViewPatterns #-}

module Main where

pattern FortyTwo :: A
pattern FortyTwo = PrivateA 42

newtype A = PrivateA Int
data B = PrivateB Int Int

pattern P :: Int -> A -> B
pattern P n a <- PrivateB n (PrivateA -> a) where
P n (PrivateA a) = PrivateB n a

f :: B -> String
f (P 2 FortyTwo) = "The meaning of life"
f _ = "Nope :("

main :: IO ()
main = do
putStrLn $ f (PrivateB 2 42)
putStrLn $ f (PrivateB 2 43)

Try it online!

关于haskell - 编写模式同义词来隐藏构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67543069/

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