2017-08-15 37 views
1

我有一個interface看起來像這樣:如何在Kotlin中構建兼容的參數/結果類型的函數?

interface FontRegionTransformer<R> { 

    fun transform(region: R, textCharacter: TextCharacter): R 
} 

我不範疇論專家,但as I have learned previously這種結構是幺(?是吧),我可以將任意數量的功能,這取R並返回R在一起。

這就是我現在所擁有的:

var image = source.getSubimage(meta.x * width, meta.y * height, width, height) 
regionTransformers.forEach { 
    image = it.transform(image, textCharacter) 
} 

這工作,但我有一個問題:我如何結合FontRegionTransformer s的List到一個單一的功能?我可以在不添加compose函數的情況下執行此操作嗎?我嘗試了reduce,但沒有點擊。

澄清:我想實現的是存儲在regionTransformers的功能組合成一個單一的功能,所以不是循環在這裏:

var image = source.getSubimage(meta.x * width, meta.y * height, width, height) 
regionTransformers.forEach { 
    image = it.transform(image, textCharacter) 
} 

我想有這樣的事情:

var image = source.getSubimage(meta.x * width, meta.y * height, width, height) 
return combinedTransformers.invoke(image)  
+0

你是什麼意思「合併'FontRegionTransformer's的'List'到一個單一的功能」是什麼意思?您能否指定您的預期輸入和輸出是什麼? – marstran

+0

我編輯了我的問題。 –

回答

2

對於組成定義,它不是很清楚,當由變壓器叫什麼textCharacter第二FontRegionTransformer<R>應該得到。在這裏,我假定傳遞給調用的是textCharacter,它自然會傳遞給第一個變壓器。

可以實現自定義組合操作的擴展FontRegionTransformer<R>

fun <R> FontRegionTransformer<R>.compose(other: FontRegionTransformer<R>) = 
    object : FontRegionTransformer<R> { 
     override fun transform(region: R, textCharacter: TextCharacter): R { 
      val firstResult = [email protected]mpose.transform(region, textCharacter) 
      return other.transform(firstResult, textCharacter) 
     } 
    } 

您可以將infix modifier添加到compose使用中綴符號a compose b,或使其overload an operator + or *,如果你喜歡叫它作爲a * b。或者對compose(a, b)調用使用非擴展頂級功能。

然後你就可以撰寫兩封FontRegionTransformer S:

val composed = first.compose(second) 

共同譜寫變壓器的列表爲一體,使用reduce

val transformers: List<FontRegionTransformer<SomeType>> = TODO() 

val composition = transformers.reduce { a, b -> a.compose(b) } 

對於FontRegionTransformer<R>是獨異,組成操作應(a ∘ (b ∘ c)應當相當於(a ∘ b) ∘ c,對於所有的a,bc)和ab實現似乎滿足了這個要求。但嚴格來說,它也應該有一箇中性元素,例如na ∘ n = n ∘ a = a,對於任何a。這兩個要求不能用Kotlin類型系統表示,而應該是合同的一部分。


一個一個語句的解決方案是,內聯composereduce電話:

val composition = transformers.reduce { a, b -> 
    object : FontRegionTransformer<SomeType> { 
     override fun transform(region: SomeType, textCharacter: TextCharacter) = 
      a.transform(region, textCharacter).let { b.transform(it, textCharacter) } 
    } 
} 
+0

所以我不能在沒有添加「撰寫」功能的情況下編寫它們?我不能使用'reduce'或其他映射函數來實現這個嗎? –

+0

@AdamArold,因爲它是一個自定義的接口,所以你需要一個自定義的函數來處理它的實例。 :)無論如何,庫函數不知道如何處理'textCharacter'。即使對於像'(T) - > R'這樣的內置函數類型,'kotlin-stdlib'中也沒有內置組合,但可以使用第三方函數編程庫,例如[funKTionale](https:/ /github.com/MarioAriasC/funKTionale)。 – hotkey

+0

順便說一下,在定製'compose'函數中,'reduce'就是您接下來要做的事情。 :) – hotkey

相關問題