我想定义一个似乎需要无限类型的东西。
要求:定义一个函数“eat”,它吃掉所有参数,除了数字“3”,对于数字“3”,它返回3。
eat 3 = 3
eat x = eat
所以基本上像“eat (+) foldl (Just 5) 3”这样的任意表达式将计算为3。但是问题在于eat的类型。它应该是什么?
我得到的最接近可运行代码是:
newtype Rec = MakeRec (Int -> Rec)
eat :: Int -> Rec
eat x = MakeRec eat
instance Show Rec where
show _ = "EAT"
这对于"eat 6"可以正常工作,但是对于"eat 6 7"则不能工作,并且如果我在定义中放置(eat 3=3),它也不起作用。
我不确定在Haskell中是否可能实现这一点。(有什么参数可以用来证明它是不可能的?)
更新:如下面的解决方案中所述,编译时需要类型信息,以便编译器知道"eat foldl 3 foldl"是否无效。因此,该问题的确切解决方案是不可能的。
Integer
参数,但它必须使用相当脆弱和非常神秘的类型黑客(TypeEq
),并且由于数字重载,它必须是eat (2 :: Integer) foldl
。 - ehird