簡體   English   中英

推斷轉換為應用程序

[英]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:

  1. 創建 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' =...
  2. 只創建一個版本的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM