我是一个Haskell新手,并且在弄清楚如何模式匹配时遇到了一些麻烦ByteString
.在[Char]
我的函数的版本是这样的:
dropAB :: String -> String
dropAB [] = []
dropAB (x:[]) = x:[]
dropAB (x:y:xs) = if x=='a' && y=='b'
then dropAB xs
else x:(dropAB $ y:xs)
Run Code Online (Sandbox Code Playgroud)
正如所料,这会过滤掉字符串中出现的所有"ab".但是,我在尝试将其应用于a时遇到问题ByteString
.
天真的版本
dropR :: BS.ByteString -> BS.ByteString
dropR [] = []
dropR (x:[]) = [x]
<...>
Run Code Online (Sandbox Code Playgroud)
产量
Couldn't match expected type `BS.ByteString'
against inferred type `[a]'
In the pattern: []
In the definition of `dropR': dropR [] = []
Run Code Online (Sandbox Code Playgroud)
[]
显然是罪魁祸首,因为它是一个常规String
而非一个ByteString
.Subbing in …
我设法构建了以下显示我的问题的"最小"示例.
如果启用了PatternSynonyms扩展
data Vec = Vec Int Int
pattern Ve x y = Vec x y
f :: (Vec, Vec) -> Vec
f (v@(Ve a b), Ve c d)
| a > b = Vec c d
| otherwise = v
Run Code Online (Sandbox Code Playgroud)
我得到了f函数的警告
Warning: Pattern match(es) are non-exhaustive
In an equation for `f': Patterns not matched: (_, _)
Run Code Online (Sandbox Code Playgroud)
如果我Ve
用Vec
它替换每一个都不会抱怨.我的奇异模式同义词如何干扰这里?
一些标准的Haskell库是否定义了这样的数据类型
data ListWithEnd e a = Cons a (ListWithEnd e a)
| End e
Run Code Online (Sandbox Code Playgroud)
这是一个列表,其终止元素带有指定类型的值?
因此与无限流ListWithEnd ()
同构[]
并且ListWithEnd Void
是同构的.或者,从不同的角度来看,ListWithEnd e a
非常接近ConduitM () a Identity e
..
我正在使用Data.Sequence
列表来获得更好的性能.使用列表,我们可以执行以下操作
foo :: [Int] -> Int
foo [] m = m
foo (x:xs) m = ...
Run Code Online (Sandbox Code Playgroud)
如何实现这一目标Data.Sequence
.我尝试过以下方法:
foo:: S.Seq Int -> Int
foo S.empty m = m
foo (x S.<: xs) m = ...
Run Code Online (Sandbox Code Playgroud)
我认为解决方案涉及使用S.viewl
和S.viewr
,但似乎无法弄清楚如何.
haskell abstract-data-type pattern-matching pattern-synonyms
考虑以下数据类型和模式同义词:
{-# LANGUAGE PatternSynonyms, NamedFieldPuns #-}
data Foo = Foo {
a :: Int
, b :: String
, c :: Maybe Bool
}
pattern Bar a b <- Foo { a, b }
pattern Baz c <- Foo { c }
Run Code Online (Sandbox Code Playgroud)
我想匹配Foo
,但得到所有的a
,b
和c
.像这样的东西(无效的Haskell):
showit :: Foo -> String
showit (Bar a b & Baz c) = show a ++ b ++ show c
Run Code Online (Sandbox Code Playgroud)
一种选择是使用ViewPattern
:
dup :: a -> (a, a) …
Run Code Online (Sandbox Code Playgroud) 我正在尝试为具有空地图的newtype创建模式同义词.
{-# Language PatternSynonyms #-}
import qualified Data.Map as Map
newtype StoreEnv = StoreEnv (Map.Map Int String)
deriving (Eq, Show)
pattern EmptyStore :: StoreEnv
pattern EmptyStore = StoreEnv Map.empty
Run Code Online (Sandbox Code Playgroud)
编译时我收到错误说"绑定位置的合格名称:Map.empty".我相信"Map.empty"应该属于我在newtype中声明的"Map.Map Int String"类型.
我的问题是是否有办法正确地为空地图添加别名.
我将不胜感激任何反馈.
我在尝试根据具有类型级别列表的GADT定义模式同义词时遇到错误.
我设法把它归结为这个例子:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE PatternSynonyms #-}
module Example where
data L (as :: [*]) where
L :: a -> L '[a]
pattern LUnit = L ()
Run Code Online (Sandbox Code Playgroud)
给我:
Example.hs:11:17:
Couldn't match type ‘a’ with ‘()’
‘a’ is a rigid type variable bound by
the type signature for Example.$bLUnit :: (t ~ '[a]) => L t
at Example.hs:11:17
Expected type: L t
Actual type: L '[()] …
Run Code Online (Sandbox Code Playgroud) 为了开始这整个事情,我正在使用定义如下的模式同义词:
{-# Language PatternSynonyms #-}
pattern x := y <- x @ y
Run Code Online (Sandbox Code Playgroud)
这允许我一次在一个参数上运行多个模式匹配。常规的 as 绑定 ( @
) 不允许左侧成为模式,但可以。
有了这个我做了以下玩具功能
{-# Language ViewPatterns #-}
f ((_:_) := (head -> y)) =
[ y ]
f [] =
[]
Run Code Online (Sandbox Code Playgroud)
我确信这不是实现这一点的最佳方法,但它是有关行为的最小工作示例。
它有一个采用单个参数的函数。它使用定义的同义词将参数与两种模式进行匹配。第一个模式匹配任何非空列表并且不进行任何绑定。第二个在列表上运行 head 函数并绑定y
到结果。
所以问题是会head
导致错误还是其他模式会阻止错误?
>>> f []
[]
Run Code Online (Sandbox Code Playgroud)
另一种模式可以阻止它!好吧,如果我按照其他顺序执行它们,那么它应该会中断,对吗?
>>> f []
[]
Run Code Online (Sandbox Code Playgroud)
>>> f' []
[]
Run Code Online (Sandbox Code Playgroud)
没有!它仍然有效。所以现在我的问题是:第二种模式到底有什么作用吗?也许视图模式具有某种智能行为,它会调用函数并在发生错误时使模式失败......
f' ((head -> y) := (_:_)) =
[ y ]
f' [] =
[]
Run Code Online (Sandbox Code Playgroud)
>>> f'' []
[*** …
Run Code Online (Sandbox Code Playgroud) 我正在为网格轴编写一个简单的ADT.在我的应用程序中,网格可以是常规的(在坐标之间有恒定的步长),也可以是不规则的(否则).当然,常规网格只是不规则网格的一种特殊情况,但在某些情况下可能需要区分它们(例如,执行一些优化).所以,我声明我的ADT如下:
data GridAxis = RegularAxis (Float, Float) Float -- (min, max) delta
| IrregularAxis [Float] -- [xs]
Run Code Online (Sandbox Code Playgroud)
但我不希望用户使用max < min
或使用无序xs
列表创建格式错误的轴.因此,我添加了"更智能"的构造函数,它们执行一些基本检查:
regularAxis :: (Float, Float) -> Float -> GridAxis
regularAxis (a, b) dx = RegularAxis (min a b, max a b) (abs dx)
irregularAxis :: [Float] -> GridAxis
irregularAxis xs = IrregularAxis (sort xs)
Run Code Online (Sandbox Code Playgroud)
我不希望用户直接创建网格,因此我不会将GridAxis
数据构造函数添加到模块导出列表中:
module GridAxis (
GridAxis,
regularAxis,
irregularAxis,
) where
Run Code Online (Sandbox Code Playgroud)
但事实证明,完成此操作后,我再也无法使用模式匹配GridAxis
了.试着用它
import qualified GridAxis as GA
test :: …
Run Code Online (Sandbox Code Playgroud) 我有以下代码,但我不知道应该输入什么??
。还是多态模式无法完成?
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
module Data.Tuple.Single.Class
( Single (..)
, pattern Single
) where
class Single t where
wrap :: a -> t a
unwrap :: t a -> a
pattern Single :: Single t => a -> t a
pattern Single a <- (unwrap -> a) where
Single a = wrap a
{-# COMPLETE Single :: ?? #-}
Run Code Online (Sandbox Code Playgroud)
GHC文件说,当所有conlikes是多态的时,您必须键入conlike。
进行时??
()
,编译成功。但是什么()
意思呢?GHC表示使用仍然不尽全力。
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE …
Run Code Online (Sandbox Code Playgroud)