Tôi cố gắng để sử dụng một dfold định nghĩa hereTạo một lần mà cho phép các loại thay đổi sau mỗi lần gọi hàm lặp đi lặp lại, để gọi một hàm n lần mà không đệ quy
dfold
:: KnownNat k
=> Proxy (p :: TyFun Nat * -> *)
-> (forall l. SNat l -> a -> (p @@ l) -> p @@ (l + 1))
-> (p @@ 0)
-> Vec k a
-> p @@ k
Về cơ bản nó là một lần mà cho phép bạn trả lại loại mới sau mỗi chu kỳ.
Tôi cố gắng để khái quát hóa bitonicSort quy định tại dự án này: https://github.com/adamwalker/clash-utils/blob/master/src/CLaSH/Sort.hs
tôi hai chức năng quan trọng cho các loại rằng dfold với generate:
bitonicSort
:: forall n a. (KnownNat n, Ord a)
=> (Vec n a -> Vec n a) --^The recursive step
-> (Vec (2 * n) a -> Vec (2 * n) a) --^Merge step
-> Vec (2 * n) a --^Input vector
-> Vec (2 * n) a --^Output vector
bitonicMerge
:: forall n a. (Ord a , KnownNat n)
=> (Vec n a -> Vec n a) --^The recursive step
-> Vec (2 * n) a --^Input vector
-> Vec (2 * n) a --^Output vector
Ví dụ sử dụng trong dự án được đề cập ở trên là:
bitonicSorterExample
:: forall a. (Ord a)
=> Vec 16 a --^Input vector
-> Vec 16 a --^Sorted output vector
bitonicSorterExample = sort16
where
sort16 = bitonicSort sort8 merge16
merge16 = bitonicMerge merge8
sort8 = bitonicSort sort4 merge8
merge8 = bitonicMerge merge4
sort4 = bitonicSort sort2 merge4
merge4 = bitonicMerge merge2
sort2 = bitonicSort id merge2
merge2 = bitonicMerge id
Tôi đã đi trước d đã tạo ra một phiên bản tổng quát hơn.
genBitonic :: (Ord a, KnownNat n) =>
(Vec n a -> Vec n a, Vec (2 * n) a -> Vec (2 * n) a)
-> (Vec (2 * n) a -> Vec (2 * n) a, Vec (4 * n) a -> Vec (4 * n) a)
genBitonic (bSort,bMerge) = (bitonicSort bSort bMerge, bitonicMerge bMerge)
bitonicBase :: Ord a => (Vec 1 a -> Vec 1 a, Vec 2 a -> Vec 2 a)
bitonicBase = (id, bitonicMerge id)
Với phiên bản này, tôi nhanh chóng có thể làm cho Sắp xếp Bitonic mới như vậy:
bSort16 :: Ord a => Vec 16 a -> Vec 16 a
bSort16 = fst $ genBitonic $ genBitonic $ genBitonic $ genBitonic bitonicBase
bSort8 :: Ord a => Vec 8 a -> Vec 8 a
bSort8 = fst $ genBitonic $ genBitonic $ genBitonic bitonicBase
bSort4 :: Ord a => Vec 4 a -> Vec 4 a
bSort4 = fst $ genBitonic $ genBitonic bitonicBase
bSort2 :: Ord a => Vec 2 a -> Vec 2 a
bSort2 = fst $ genBitonic bitonicBase
Mỗi Sắp xếp công việc với một vector có kích thước quy định.
testVec16 :: Num a => Vec 16 a
testVec16 = 9 :> 2 :> 8 :> 6 :> 3 :> 7 :> 0 :> 1 :> 4 :> 5 :> 2 :> 8 :> 6 :> 3 :> 7 :> 0 :> Nil
testVec8 :: Num a => Vec 8 a
testVec8 = 9 :> 2 :> 8 :> 6 :> 3 :> 7 :> 0 :> 1 :> Nil
testVec4 :: Num a => Vec 4 a
testVec4 = 9 :> 2 :> 8 :> 6 :> Nil
testVec2 :: Num a => Vec 2 a
testVec2 = 2 :> 9 :> Nil
ghi chú nhanh:
Tôi cố gắng để các áp dụng "genBitonic" thành "bitonicBase" lần t.
Tôi đang sử dụng Clash để tổng hợp này để VHDL, vì vậy tôi không thể sử dụng đệ quy để áp dụng t lần
Chúng tôi sẽ luôn luôn được sắp xếp một kích thước vec 2^t vào một vec có cùng kích thước
"Vec na" là một vector của các kích thước n và gõ một
tôi muốn thực hiện một chức năng mà tạo ra các chức năng cho một Vec nhất định. Tôi tin rằng bằng cách sử dụng dfold hoặc dtfold, là con đường chính xác ở đây.
Tôi muốn làm gấp với chức năng như genBitonic
.
Sau đó, sử dụng fst
để lấy hàm tôi cần để sắp xếp.
tôi có hai kiểu dáng thể:
Một: Gấp sử dụng thành phần để có được một chức năng rằng có cơ sở.
bSort8 :: Ord a => Vec 8 a -> Vec 8 a
bSort8 = fst $ genBitonic.genBitonic.genBitonic $ bitonicBase
Trước khi cơ sở đã được trả lời nó sẽ có kết quả trong một cái gì đó giống như
**If composition was performed three times**
foo3 ::
(Ord a, KnownNat n) =>
(Vec n a -> Vec n a, Vec (2 * n) a -> Vec (2 * n) a)
-> (Vec (2 * (2 * (2 * n))) a -> Vec (2 * (2 * (2 * n))) a,
Vec (4 * (2 * (2 * n))) a -> Vec (4 * (2 * (2 * n))) a)
Hai: ý tưởng thứ hai là sử dụng các bitonicBase như giá trị b để bắt đầu tích lũy trên. Điều này sẽ dẫn đến kết quả trực tiếp trong biểu mẫu tôi cần trước khi tôi áp dụng fst
.
Chỉnh sửa vecAcum
chỉ có nghĩa là giá trị xây dựng bên trong của dfold
.
Trong ví dụ dfold họ gấp sử dụng một :>
mà chỉ là dạng vector của các nhà điều hành danh sách :
>>> :t (:>)
(:>) :: a -> Vec n a -> Vec (n + 1) a
Những gì tôi muốn làm là lấy một tuple của hai chức năng như:
genBitonic :: (Ord a, KnownNat n) =>
(Vec n a -> Vec n a, Vec (2 * n) a -> Vec (2 * n) a)
-> (Vec (2 * n) a -> Vec (2 * n) a, Vec (4 * n) a -> Vec (4 * n) a)
Và soạn chúng. Vì vậy genBitonic . genBitonic
sẽ phải loại:
(Vec n a -> Vec n a, Vec (2 * n) a -> Vec (2 * n) a)
-> (Vec (2 * (2 * n)) a -> Vec (2 * (2 * n)) a, Vec (4 * (2 * n)) a -> Vec (4 * (2 * n)) a)
Vì vậy, sau đó các chức năng cơ bản sẽ là những gì củng cố các loại. ví dụ:
bitonicBase :: Ord a => (Vec 1 a -> Vec 1 a, Vec 2 a -> Vec 2 a)
bitonicBase = (id, bitonicMerge id)
bSort4 :: Ord a => Vec 4 a -> Vec 4 a
bSort4 = fst $ genBitonic $ genBitonic bitonicBase
Tôi đang sử dụng lệnh dfold để tạo hàm cho vectơ có độ dài n tương đương với thực hiện đệ quy trên vectơ có độ dài n.
tôi đã cố gắng:
tôi cố gắng làm theo tấm gương được liệt kê dưới dfold
data SplitHalf (a :: *) (f :: TyFun Nat *) :: *
type instance Apply (SplitHalf a) l = (Vec (2^l) a -> Vec (2^l) a, Vec (2^(l + 1)) a -> Vec (2^(l + 1)) a)
generateBitonicSortN2 :: forall k a . (Ord a, KnownNat k) => SNat k -> Vec (2^k) a -> Vec (2^k) a
generateBitonicSortN2 k = fst $ dfold (Proxy :: Proxy (SplitHalf a)) vecAcum base vecMath
where
vecMath = operationList k
vecAcum :: (KnownNat l, KnownNat gl, Ord a) => SNat l
-> (SNat gl -> SplitHalf a @@ gl -> SplitHalf a @@ (gl+1))
-> SplitHalf a @@ l
-> SplitHalf a @@ (l+1)
vecAcum l0 f acc = undefined -- (f l0) acc
base :: (Ord a) => SplitHalf a @@ 0
base = (id,id)
general :: (KnownNat l, Ord a)
=> SNat l
-> SplitHalf a @@ l
-> SplitHalf a @@ (l+1)
general _ (x,y) = (bitonicSort x y, bitonicMerge y)
operationList :: (KnownNat k, KnownNat l, Ord a)
=> SNat k
-> Vec k
(SNat l
-> SplitHalf a @@ l
-> SplitHalf a @@ (l+1))
operationList k0 = replicate k0 general
Tôi đang sử dụng các phần mở rộng mã nguồn dfold sử dụng
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE Trustworthy #-}
Lỗi tin nhắn:
Sort.hs:182:71: error:
* Could not deduce (KnownNat l) arising from a use of `vecAcum'
from the context: (Ord a, KnownNat k)
bound by the type signature for:
generateBitonicSortN2 :: (Ord a, KnownNat k) =>
SNat k -> Vec (2^k) a -> Vec (2^k) a
at Sort.hs:181:1-98
Possible fix:
add (KnownNat l) to the context of
a type expected by the context:
SNat l
-> (SNat l0
-> (Vec (2^l0) a -> Vec (2^l0) a,
Vec (2^(l0 + 1)) a -> Vec (2^(l0 + 1)) a)
-> (Vec (2^(l0 + 1)) a -> Vec (2^(l0 + 1)) a,
Vec (2^((l0 + 1) + 1)) a -> Vec (2^((l0 + 1) + 1)) a))
-> SplitHalf a @@ l
-> SplitHalf a @@ (l + 1)
* In the second argument of `dfold', namely `vecAcum'
In the second argument of `($)', namely
`dfold (Proxy :: Proxy (SplitHalf a)) vecAcum base vecMath'
In the expression:
fst $ dfold (Proxy :: Proxy (SplitHalf a)) vecAcum base vecMath
Sort.hs:182:84: error:
* Could not deduce (KnownNat l0) arising from a use of `vecMath'
from the context: (Ord a, KnownNat k)
bound by the type signature for:
generateBitonicSortN2 :: (Ord a, KnownNat k) =>
SNat k -> Vec (2^k) a -> Vec (2^k) a
at Sort.hs:181:1-98
The type variable `l0' is ambiguous
* In the fourth argument of `dfold', namely `vecMath'
In the second argument of `($)', namely
`dfold (Proxy :: Proxy (SplitHalf a)) vecAcum base vecMath'
In the expression:
fst $ dfold (Proxy :: Proxy (SplitHalf a)) vecAcum base vecMath
Failed, modules loaded: none.
** CHỈNH SỬA ** Đã thêm nhiều chi tiết hơn.
Chúng ta hãy [tiếp tục cuộc thảo luận này trong trò chuyện] (http://chat.stackoverflow.com/rooms/135612/discussion-between-lambdascientist-and-user2407038). – LambdaScientist
Chính xác thì bạn đang cố gắng điền gì (có thể là phần thân 'generateBitonicSortN2')? Tôi đang gặp khó khăn khi nhìn thấy những chức năng mà bạn đưa ra là những khó khăn khó khăn, những chức năng nào là một phần của giải pháp được đề xuất của bạn, và vấn đề thực tế là gì. – Alec