[英]Inferred conversion to applicative
我正在使用硬件描述工具 Clash。 雖然這是一個硬件描述工具,但我的問題純粹是關於 Haskell。
有一個數據類型為data Signal dom a =...
這個數據類型有一個 Applicative 實例如下:
instance Applicative (Signal domain) where
pure = signal#
(<*>) = appSignal#
我已經定義了一些可以明智地采用Signal dom (Foo ab)
或Foo ab
的函數。 也就是說,它們可以獲取包裝在 Applicative 中的值,也可以獲取該值然后調用pure
來自己包裝它。
我看到了兩種(丑陋的)方法來實現這樣的 function:
創建 function 的兩個版本,一個采用“裸”值,另一個采用 Applicative。 在第一個 function 中,我調用pure
然后委托給第二個 function。 這些函數如下所示:
f:: (Foo ab) -> Signal dom Baz -> Signal dom Bar f = f'. pure f':: Signal dom (Foo ab) -> Signal dom Baz -> Signal dom Bar f' =...
只創建一個版本的 function,然后期望用戶根據需要調用pure
。
我想創建一個類型類來解決這個問題,其中Foo ab
的實例是pure
的,而Signal dom (Foo ab)
的實例是id
。 但我看不出有什么方法可以定義這樣的事情。
有沒有辦法定義一個類型類,或者有沒有我忽略的另一種解決方案?
當然,如果他們可以采用應用程序,那么他們可以采用純值。 這就是為什么我們有pure
. 它可能不是最“流暢”的東西,但將pure
放在調用站點確實有其優點 - 即代碼的讀者知道這個值不會改變,而且它是被允許的。
在任何情況下,如果參數類型是像Foo
這樣的固定數據類型,那么您可以:
class IsSignal dom a where
type Arg dom a :: *
toSignal :: a -> Signal dom (Arg dom a)
instance IsSignal dom (Foo a b) where
type Arg dom (Foo a b) = Foo a b
toSignal = pure
-- repeat this instance for every concrete type you expect
instance IsSignal dom (Signal dom a) where
type Arg dom (Signal dom a) = a
toSignal = id
f :: (IsSignal dom s, Arg dom s ~ Foo a b) => s -> Signal dom Baz -> Signal dom b
f a b = -- ... toSignal a ...
這是否值得取決於你。
如果您希望它適用於多態類型,例如
g :: a -> Signal dom Baz -> Signal dom a
據我所知,沒有好的解決方案。 有些涉及重疊實例的事情可能看起來適用於最簡單的示例,但它們很容易中斷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.