2014-02-21 74 views
0

這是一個簡單的例子類型推斷和隱式鏈接

我有以下代碼:

import scala.language.implicitConversions 

trait Mapping[I, O] 
trait KeyMapping[K, I, O] 

implicit def toMapping[I, O](s: I => O): Mapping[I, O] = ??? 
implicit def toKeyMapping[K, I, O](s: (K, I => O))(
    implicit ev: (I => O) => Mapping[I, O]): KeyMapping[K, I, O] = ??? 

def test[K, I, O, M](s: M)(
    implicit ev: M => KeyMapping[K, I, O] 
):KeyMapping[K, I, O] = ??? 

val x = test(1 -> {s:String => true}) 
      ^

這提供了以下錯誤:

type mismatch; 
found: ((Int, Nothing => Boolean)) => KeyMapping[Int,Nothing,Boolean] 
required: ((Int, String => Boolean)) => KeyMapping[Int,Input,Boolean] 

這是爲什麼?

可以解決這個問題嗎?

回答

0

我解決了它通過使用隱式轉換器而不是隱式轉換。

import scala.language.implicitConversions 

trait Mapping[I, O] 
trait KeyMapping[K, I, O] 

trait MappingConverter[M, I, O] { 
    def convert(m: M): Mapping[I, O] 
} 

trait KeyMappingConverter[M, K, I, O] { 
    def convert(m: M): KeyMapping[K, I, O] 
} 

implicit def toMapping[I, O] = 
    new MappingConverter[I => O, I, O] { 
    def convert(m: I => O): Mapping[I, O] = ??? 
    } 

implicit def toKeyMapping[K, I, O, M](
    implicit mapping: MappingConverter[M, I, O]) = 
    new KeyMappingConverter[(K, M), K, I, O] { 
    def convert(m: (K, M)): KeyMapping[K, I, O] = ??? 
    } 

def test[K, I, O, M](s: M)(
    implicit converter: KeyMappingConverter[M, K, I, O]): KeyMapping[K, I, O] = ??? 

val x = test(1 -> { s: String => true }) 
1

我正想說:

def test[K, I, O](s: (K, I => O))(
     implicit ev: ((K, I => O)) => KeyMapping[K, I, O] 
):KeyMapping[K, I, O] = ??? 

號男,並注意額外的括號。它會autotuple嘗試一個適用,但不是未實現。

你可以(在2.10 -Yinfer-debug)在2.11使用-Ytyper-debug看到它推斷Nothing

功能在它們的輸入中是相反的,因此推斷Nothing意味着它的最寬類型爲I => O。您可以競爭Mapping轉換,其中之一需要Nothing

+0

我其實需要'M',我忘了說這是個簡單的例子 – EECOLOR