我正在嘗試在 Haskell 中撰寫一個函式來生成多維串列。
(從技術上講,我使用的是 Curry,但我的理解是它主要是 Haskell 的超集,而且我正在嘗試做的事情對 Haskell 也很常見。)
經過一番摸索,我意識到我最初想要的函式(m_array generating_function list_of_dimensions,給出一個嵌套深度等于 的串列length list_of_dimensions)可能與它們的型別系統本身不一致,因為(AFAICT)串列的嵌套深度是它的一部分型別,我的函式想要回傳嵌套深度因引數值而異的值,這意味著它想要回傳型別因值而異的值一個引數,它(AFAICT)在 Haskell 中不受支持。(如果我錯了,并且可以這樣做,請告訴我。)此時我轉到下一段,但是如果我錯過了一個解決方法,它采用非常相似的引數并且仍然輸出嵌套串列,讓我知道。就像,也許如果您可以將索引編碼為某種資料型別,該資料型別在其型別中隱式包含嵌套級別,并使用 eg 進行實體化dimensions 5 2 6 ...,也許這可行?不確定。
無論如何,我想也許我可以通過嵌套函式本身來編碼嵌套深度,同時仍然保持引數可管理。這確實有效,我最終得到了以下結果:
ma f (l:ls) idx = [f ls (idx [i]) | i <- [0..(l-1)]]
但是,到目前為止,使用起來仍然有點笨拙:您需要嵌套呼叫,例如
ma (ma (ma (\_ i -> 0))) [2,2,2] []
(順便說一句,給出[[[0,0],[0,0]],[[0,0],[0,0]]]。如果你使用(\_ i -> i),它會用相應元素的索引填充陣列,這是我希望保持可用的結果,但可能是一個令人困惑的例子。)
我更愿意盡量減少必要的樣板檔案。如果我不能只是打電話
ma (\_ i -> i) [2,2,2]
我希望能夠打電話,在最壞的情況下,
ma ma ma (\_ i -> i) [2,2,2] []
但是,如果我嘗試這樣做,則會出現錯誤。據推測,引數串列正在以對函式沒有意義的方式進行劃分。我花了大約半個小時在谷歌上搜索和試驗,試圖找出 Haskell 決議像這樣的函式字串的機制,但我還沒有找到一個明確的解釋,而且我無法理解。所以,正式的問題:
- Haskell 如何決議 eg
f1 f2 f3 x y z?引數是如何分配的?它依賴于函式的簽名,還是只是嘗試f1使用 5 個引數進行呼叫? - 有沒有一種重組方法
ma可以允許在沒有括號的情況下呼叫它?(最多允許添加兩個輔助函式,例如maStart ma ma maStop (\_ i -> i) [1,2,3,4] [],如有必要。)
uj5u.com熱心網友回復:
您在令人頭疼的段落中想要的功能是可以直接實作的——盡管有點吵。使用GADTs和DataKinds,值可以通過數字引數化。您將無法直接使用串列,因為它們沒有在型別中提及它們的長度,而是一個非常有效的簡單變體。這是它的外觀。
{-# Language DataKinds #-}
{-# Language GADTs #-}
{-# Language ScopedTypeVariables #-}
{-# Language StandaloneDeriving #-}
{-# Language TypeOperators #-}
import GHC.TypeLits
infixr 5 :
data Vec n a where
O :: Vec 0 a -- O is supposed to look a bit like a mix of 0 and []
(: ) :: a -> Vec n a -> Vec (n 1) a
data FullTree n a where
Leaf :: a -> FullTree 0 a
Branch :: [FullTree n a] -> FullTree (n 1) a
deriving instance Show a => Show (Vec n a)
deriving instance Show a => Show (FullTree n a)
ma :: forall n a. ([Int] -> a) -> Vec n Int -> FullTree n a
ma f = go [] where
go :: [Int] -> Vec n' Int -> FullTree n' a
go is O = Leaf (f is)
go is (l : ls) = Branch [go (i:is) ls | i <- [0..l-1]]
在 ghci 中嘗試一下:
> ma (\_ -> 0) (2 : 2 : 2 : O)
Branch [Branch [Branch [Leaf 0,Leaf 0],Branch [Leaf 0,Leaf 0]],Branch [Branch [Leaf 0,Leaf 0],Branch [Leaf 0,Leaf 0]]]
> ma (\i -> i) (2 : 2 : 2 : O)
Branch [Branch [Branch [Leaf [0,0,0],Leaf [1,0,0]],Branch [Leaf [0,1,0],Leaf [1,1,0]]],Branch [Branch [Leaf [0,0,1],Leaf [1,0,1]],Branch [Leaf [0,1,1],Leaf [1,1,1]]]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/400948.html
上一篇:將“派生通過”與型別系列一起使用
