gpt4 book ai didi

haskell - 是否可以使用您自己的数据类型模拟函数?

转载 作者:行者123 更新时间:2023-12-04 01:34:07 27 4
gpt4 key购买 nike

是否可以使用您自己的数据类型和一些 GHC 扩展来模拟函数?我想做的是例如

(想象的语法)

data MyFunc = MyFunc String (Int->Int)

instance (Int->Int) MyFunc where
($) (MyFunc _ f) i = f i

inc = MyFunc "increment" (1+)

test = inc 1

IE。带有一些元信息并且可以进行模式匹配的数据,但仍然可以像常规函数一样调用。现在,我知道我可以定义自己的中缀运算符,如 $$并调用 inc $$ 1 ,但能够使用常规函数调用语法在嵌入式 DSL 中将非常有用。

最佳答案

是的,它可以在有限的范围内完成。

但首先我们需要

{-# LANGUAGE Rank2Types #-}

让我们定义
data M a b = M { name :: Int -> String -> String, eval :: a -> b }

我正在为您的名字添加更多结构,以便获得更好的节目支持。 ;)

然后让我们定义一个类:
class Magic m where
magic :: M a b -> m a b

instance Magic M where
magic = id

instance Magic (->) where
magic (M _ f) = f

现在,考虑类型:
type MyFunc a b = forall m. Magic m => m a b
magic的结果类型是 (a -> b)M a b .

所以可以作为 MyFunc的成员.现在,这种类型有点不令人满意,因为你不能在它上面调度实例,但这确实意味着
inc :: MyFunc Int Int
inc = magic (M (const (showString "inc")) (+1))

test :: Int
test = inc 1

工作得很好。

我们甚至可以用一种相当不错的方式来展示它们。即使我们不能在 MyFunc 上使用 show ,我们可以定义为 M .
instance Show (M a b) where
showsPrec d (M s _) = s d

然后我们可以制作一个可以应用到 M a b的函数(以及任何 MyFunc 的扩展)以获取 M a b .
m :: M a b -> M a b
m = id

我们可以定义一个特殊的组合子来显示 MyFunc年代:
showM :: MyFunc a b -> String
showM f = show (m f)

然后我们就可以玩了。我们可以定义 MyFunc 的组合。 s。
infixr 9 .#
(.#) :: MyFunc b c -> MyFunc a b -> MyFunc a c
f .# g = magic (M
(\d -> showParen (d > 9) $ showsPrec 10 (m f) .
showString " . " .
showsPrec 9 (m g))
(f . g))

inc2 :: MyFunc Int Int
inc2 = inc .# inc

test2 :: Int
test2 = inc2 1

bar, baz :: String
bar = showM inc
baz = showM inc2

而且因为我给名称提供了足够的结构,我们甚至可以为更复杂的组合获得正确的括号,而没有不必要的括号。
*Main> showM $ inc2 .# inc
"(inc . inc) . inc"

*Main> showM $ inc .# inc2
"inc . inc . inc"

但请记住,您将无法为 MyFunc 定义任何实例。 , 因为它只能是 type ,而不是 newtype .为了定义实例,您必须在 M 上定义它们。 ,然后使用 m转换为该类型,以便隐式调度具有可抓取的类型。

由于 rank 2 类型,如果您在本地环境中大量使用这些,您可能还需要打开 NoMonoLocalBinds和/或 NoMonomorphismRestriction .

关于haskell - 是否可以使用您自己的数据类型模拟函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6482970/

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