我正在尝试根据比例模式匹配:
isValid :: Ratio Int -> Bool
isValid (num % den) = ...
Run Code Online (Sandbox Code Playgroud)
但是,这会产生:
Parse error in pattern: num % den
Run Code Online (Sandbox Code Playgroud)
有趣的是,Data.Ratio
包以这种方式定义numerator
和denominator
功能,但与:%
运营商:
numerator (x :% _) = x
denominator (_ :% y) = y
Run Code Online (Sandbox Code Playgroud)
但是,我无法访问后一种运营商.
任何人都可以解释为什么我的模式匹配不起作用以及我如何解决它?
我并不是作为Eq的成员.我的代码:
data Race = Terran | Zerg | Protoss deriving (Eq, Show, Read);
data MU = MU Race Race deriving (Eq, Show);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我定义了例如(MU Terran Zerg)
.我想创建一个数据构造函数TvZ
,它在intance的各个方面基本相同,所以我可以匹配一个函数模式:
foo TvZ = ...
Run Code Online (Sandbox Code Playgroud)
而不是必须做
foo (MU Terran Zerg) = ...
Run Code Online (Sandbox Code Playgroud)
如果将其分配给变量,则无法执行此操作 tvZ = (MU Terran Zerg)
我想要做的另一件事是做短形式,如在制造型构造T
和Terran
相同的.
最后一点,medivac速度提升需要一个小的nerf我觉得.
这给了我以下错误
不在范围内:数据构造函数
Blah
为什么?我以为我可以在任何地方使用类型同义词Person
data Person = Person { weight :: Int, height :: Int }
type Blah = Person
person1 :: Blah
person1 = Blah 80 187
Run Code Online (Sandbox Code Playgroud) 如何在Haskell中定义宏常量?特别是,我想在没有第二个模式匹配的情况下运行以下代码片段重叠.
someconstant :: Int
someconstant = 3
f :: Int -> IO ()
f someconstant = putStrLn "Arg is 3"
f _ = putStrLn "Arg is not 3"
Run Code Online (Sandbox Code Playgroud) 可能没有办法做到这一点,但我只是想问以防万一.
我有一个数据类型,这是一个像这样的简单元组:
data Tup a = T a a
Run Code Online (Sandbox Code Playgroud)
我有一个这样的模式同义词:
pattern (:?) :: () => Floating a => a -> a -> Tup a
pattern (x :? y) <- T x (sqrt->y)
Run Code Online (Sandbox Code Playgroud)
匹配T x y
,但y平方根.所以:
let (_ :? y) = T 1 4 in y
Run Code Online (Sandbox Code Playgroud)
是
2.0
Run Code Online (Sandbox Code Playgroud)
我也希望能够:?
用作构造函数,所以我可以做一些很酷的事情:
1 :? 2
Run Code Online (Sandbox Code Playgroud)
评估到
T 1.0 4.0
Run Code Online (Sandbox Code Playgroud)
当然我必须手动指定同构,但有没有任何语法或语言功能可以让我得到这种行为?
假设我有以下代码(文本<>
是速记,实际上不是代码的一部分):
data A = <something>
defaultA :: A
defaultA = <Really complicated expression of type A>
Run Code Online (Sandbox Code Playgroud)
现在我想要一个函数模式匹配defaultA
,如下所示:
f defaultA = <case 1>
f _ = <case 2>
Run Code Online (Sandbox Code Playgroud)
但是,defaultA
第一行变为新变量,而不是表示参数相等的条件defaultA
.我知道实现我想要的最好的方式是:
f x | x == defaultA = <case 1>
f _ = <case 2>
Run Code Online (Sandbox Code Playgroud)
有谁知道更好的方法?
让我说我有一个像这样的语言的GADT(我的实际语言要复杂得多,大约50个构造函数,但这是一个简化的例子):
data Expr t where
Add :: Expr t -> Expr t -> Expr t
Sub :: Expr t -> Expr t -> Expr t
Mult :: Expr t -> Expr t -> Expr t
Negate :: Expr t -> Expr t
Abs :: Expr t -> Expr t
Scalar :: t -> Expr t
Run Code Online (Sandbox Code Playgroud)
现在让我们定义另一种数据类型:
data BinOpT = AddOp | SubOp | MultOp
Run Code Online (Sandbox Code Playgroud)
另外,假设我有以下功能:
stringBinOp :: BinOpT -> String
stringBinOp AddOp = "+"
stringBinOp SubOp = "-"
stringBinOp MultOp …
Run Code Online (Sandbox Code Playgroud) 假设一种模式:
pattern P :: [Int]
pattern P <- a:_
Run Code Online (Sandbox Code Playgroud)
我可以以某种方式使用a
该功能f
吗?
f :: [Int] -> Int
f P = a
Run Code Online (Sandbox Code Playgroud)
上面的代码生成错误Not in scope: 'a'
.
考虑以下:
module MyModule (
A(FortyTwo), -- Note we don't expose PrivateA
B(P) -- Nor PrivateB
) where
pattern FortyTwo = A 42
newtype A = PrivateA Int
data B = PrivateB Int Int
pattern P :: Int -> A -> B
Run Code Online (Sandbox Code Playgroud)
我怎样才能写模式P
?
基本上我可以说:
f :: B -> String
f (P 2 FortyTwo) = "The meaning of life"
Run Code Online (Sandbox Code Playgroud)
也就是说,能够在不引用私有构造函数的情况PrivateA
下PrivateB
直接在定义它们的模块外部进行模式匹配。
假设我想删除列表末尾的所有零:
removeEndingZeros :: (Num a, Eq a) => [a] -> [a]
removeEndingZeros (xs ++ [0]) = removeEndingZeros xs
removeEndingZeros xs = xs
Run Code Online (Sandbox Code Playgroud)
由于(++)
参数中的运算符,这不起作用.如何通过模式匹配确定列表的结尾?