2015-11-27 4 views
2

Вот фиктивный пример:Укажите контекст, откуда приходит термин в Haskell

class Test a b where 
    witness :: a 

f :: Test a b => a 
f = witness 

Haskell затем сказать

Could not deduce (Test a b0) arising from a use of ‘witness’ 
from the context (Test a b) 
    bound by the type signature for f :: Test a b => a 
    at test.hs:8:6-18 
The type variable ‘b0’ is ambiguous 
Relevant bindings include f :: a (bound at test.hs:9:1) 
In the expression: witness 
In an equation for ‘f’: f = witness 

Ошибка происходит из того факта, что Haskell не может вывести тип переменной b0 и решение будет следует удалить параметр b из определения класс Test. Но на самом деле я не могу.

Мой вопрос: существует ли способ для объяснения идентификатора b0 с явным параметром b в строке f :: Test a b => a?

Спасибо.

+2

добавляет 'Proxy b' аргумент (или даже' прокси b') в 'witness' вариант? –

+3

В качестве альтернативы, добавляется функция «a -> b» с функциональной зависимостью? –

+0

Или измените его на 'witness :: Constant a b' – rampion

ответ

1

конкретизации Joachim Breitner's suggestion, вы могли бы использовать witness если вы можете изменить его тип подписи, чтобы быть proxy b -> a аргумент или Constant a b.

Эти два подхода в основном эквивалентны, так что это вопрос предпочтения:

{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE ScopedTypeVariables #-} 
module SO33958506 where 

import Data.Functor.Constant 
import Data.Proxy 

class Test a b where 
    constantWitness :: Constant a b 
    proxyWitness :: proxy b -> a 

constantWitnessWithProxy :: forall proxy a b. Test a b => proxy b -> a 
constantWitnessWithProxy _ = getConstant $ (constantWitness :: Constant a b) 

proxyWitnessAsConstant :: forall a b. Test a b => Constant a b 
proxyWitnessAsConstant = Constant $ proxyWitness (Proxy :: Proxy b) 
+0

Спасибо всем! Но для каких конструкторов типа Constant и proxy? – abitbol

+0

Они привносят тип 'b' в область видимости, поэтому компилятор знает, какой экземпляр' Test a b' использовать. Если в области видимости находится только 'a', у нее нет способа определить, какой экземпляр будет использоваться, поскольку могут существовать экземпляры' Test a b' для нескольких разных 'b' s, заданных 'a'. – rampion

Смежные вопросы