Я хочу создать рекурсивный тип экземпляра на основе кортежей. Я ищу что-то подобное:Haskell Рекурсивный тип классов
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
К сожалению, haskell не может решить проблему. Любая причина?
Предположительно, вы хотите, чтобы Haskell использовал первый экземпляр над вторым, когда это было возможно. К сожалению, при попытке решить, какой экземпляр использовать, когда есть несколько кандидатов, GHC только смотрит на голову экземпляра, чтобы попытаться определить, что является наиболее конкретным. – Alec
Но в тех случаях, когда я писал, решение должно быть детерминированным, так как в tryFunc2 второй экземпляр является единственным, у которого String является аргументом второго типа, а в случае tryFunc1 - это комбинация первого и второго , Существует только одно возможное решение. –
@FernandoRincon Дизайн системы типа Haskell гарантирует гораздо больше, чем просто уникальное решение: он гарантирует, что решение можно найти, не выполняя поиск (откат). Это компромисс между эффективностью и выразительностью, и, на мой взгляд, он хорошо послужил языку. Предполагаемые вами экземпляры, в общем, требуют от компилятора выполнить поиск, чтобы найти решение, даже если оно уникально - и поэтому отклоняются. –