我試過在web和stackexchange中搜索,但是令人驚訝的是沒有人問到如何在下面的表單中計算Haskell中元組的長度。如何計算Haskell中元組的長度?
所以假設你在Haskell中有(1,2,3,4)或(1,3,5,6,7)這樣的元組,並希望寫出計算元組長度的長度函數。我怎樣才能做到這一點?對於列表,我知道如何使用遞歸而不顯式調用內置函數。但是元組是不同的,我不能用「頭」 - 「尾」區分。
該方法是否會涉及創建新的數據類型?
我試過在web和stackexchange中搜索,但是令人驚訝的是沒有人問到如何在下面的表單中計算Haskell中元組的長度。如何計算Haskell中元組的長度?
所以假設你在Haskell中有(1,2,3,4)或(1,3,5,6,7)這樣的元組,並希望寫出計算元組長度的長度函數。我怎樣才能做到這一點?對於列表,我知道如何使用遞歸而不顯式調用內置函數。但是元組是不同的,我不能用「頭」 - 「尾」區分。
該方法是否會涉及創建新的數據類型?
一個可能的答案(僅使用基本庫)是
import Data.Data
import Data.Functor.Const
length :: Data a => a -> Int
length =
getConst .
gfoldl (\(Const c) _ -> Const (c+1)) (const 0)
我介紹了在倫敦哈斯克爾這一主題的整個談話最近。幻燈片是here,但該視頻尚未發佈。
值得注意的是,這將給出「長度信息」不僅適用於元組,而且適用於其他各種數據結構,可能並不總是與預期的結果。 – leftaroundabout
你不覺得在這一切的原因是,它不會使一個很大的意義來算一個元組的長度:
這就是說,它可以實現自己的目標,但是這不應該是一個正常的功能,但一個型級別的功能,又名型家庭。使用singleton類型NATS:
{-# LANGUAGE TypeFamilies, DataKinds #-}
import Data.Singletons
import Data.Singletons.TypeLits
type family TupLength a :: Nat where
TupLength() = 0
TupLength (a,b) = 2
TupLength (a,b,c) = 3
TupLength (a,b,c,d) = 4
-- ...
TupLength x = 1
然後
> mapM_ print [ natVal (sing :: SNat (TupLength()))
, natVal (sing :: SNat (TupLength (Int,String,Double)))
, natVal (sing :: SNat (TupLength Bool)) ]
0
3
1
什麼會這樣的函數的類型是什麼? – sepp2k
這就是問這個問題的要點。我無法理解這將如何成爲可能。不同長度的元組不會共享相同的類型,我不知道如何利用創建新數據類型來支持長度函數。 –
出於好奇,你爲什麼要這樣做?元組的長度在編譯時是固定的,所以不需要「計算」任何東西。你可以像'class TupLen a tupLen :: a - > Int'那樣使用類實例TupLen(a,b),其中tupLen _ = 2',&c。但這不是很有用。 –