Haskell递归类型类

Fer*_*con 1 haskell typeclass

我想基于元组创建递归实例类型.我要找的是类似的东西:

class Provider a b where
  getInstance :: a -> b

instance Provider a b => Provider (x, a) b where
  getInstance (x, a) = getInstance a

instance Provider (b, x) b where
  getInstance (b, _) = b

tryFunc1 :: Int
tryFunc1 =
  let provider = ("test", (10, ())) :: (String, (Int, ()))
  in getInstance provider

tryFunc2 :: String
tryFunc2 =
  let provider = ("test", (10, ())) :: (String, (Int, ()))
  in getInstance provider
Run Code Online (Sandbox Code Playgroud)

不幸的是,haskell无法解决这个问题.任何原因?

Ale*_*lec 6

解决方案是停止使用已弃用的OverlappingInstancespragma并开始使用per实例OVERLAPPINGOVERLAPPABLEpragma.只有这个改变:

instance {-# OVERLAPPABLE #-} Provider a b => Provider (x, a) b where
  getInstance (x, a) = getInstance a

instance {-# OVERLAPPING #-} Provider (b, x) b where
  getInstance (b, _) = b
Run Code Online (Sandbox Code Playgroud)

我会tryFunc1成为10tryFunc2成为"test".


从技术上讲,你只需要OVERLAPPABLE或者OVERLAPPINGpragma,但我相信在这种情况下两者都是好的做法...而且,我认为这是你想要的行为,但请注意,这只是你得到的任何类型的第一个正在寻找(所以getInstance (10, (20, ())) :: Int给我10不是 20)

信息的良好来源是门票跟踪功能的创作.