Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


5 questions online user: 48

0
votes
answers
34 views
+10

斯卡拉:正則表達式模式匹配

0

我有以下的輸入字符串斯卡拉:正則表達式模式匹配

"/horses/[email protected]" 
"/Goats/[email protected]" 
"/CATS/[email protected]" 

我想獲得

"horses", "c132", "[email protected]" 
"Goats", "b-01", "[email protected]" 
"CATS", "001", "[email protected]" 

我嘗試以下

StandardTokenParsers以下爲輸出

import scala.util.parsing.combinator.syntactical._ 
val p = new StandardTokenParsers { 
lexical.reserved ++= List("/", "?", "XXX=") 
def p = "/" ~ opt(ident) ~ "/" ~ opt(ident) ~ "?" ~ "XXX=" ~ opt(ident) 
} 
p: scala.util.parsing.combinator.syntactical.StandardTokenParsers{def p: this.Parser[this.~[this.~[this.~[String,Option[String]],String],Option[String]]]} = [email protected] 

scala> p.p(new p.lexical.Scanner("/horses/[email protected]")) 
warning: there was one feature warning; re-run with -feature for details 
res3: p.ParseResult[p.~[p.~[p.~[String,Option[String]],String],Option[String]]] = 
[1.1] failure: ``/'' expected but ErrorToken(illegal character) found 

/horses/[email protected] 
^ 

正則表達式

import scala.util.matching.regex 
val p1 = "(/)(.*)(/)(.*)(?)(XXX)(=)(.*)".r 
p1: scala.util.matching.Regex = (/)(.*)(/)(.*)(?)(XXX)(=)(.*) 

scala> val p1(_,animal,_,id,_,_,_,company) = "/horses/[email protected]" 
scala.MatchError: /horses/[email protected] (of class java.lang.String) 
    ... 32 elided 

是否有人可以幫忙嗎?謝謝!

沙发
0
0

您的模式看起來像/(desired-group1)/(desired-group2)?XXX=(desired-group3)

所以,正則表達式將是

scala> val extractionPattern = """(/)(.*)(/)(.*)(?XXX=)(.*)""".r 
extractionPattern: scala.util.matching.Regex = (/)(.*)(/)(.*)(?XXX=)(.*) 

- 逃脫?字符。

它是如何工作的,

Full match `/horses/[email protected]` 
Group 1. `/` 
Group 2. `horses` 
Group 3. `/` 
Group 4. `c132` 
Group 5. `?XXX=` 
Group 6. `[email protected]` 

現在,應用它給你的組中的所有的正則表達式匹配

scala> extractionPattern.findAllIn("""/horses/[email protected]""") 
         .matchData.flatMap{m => m.subgroups}.toList 
res15: List[String] = List(/, horses, /, c132, ?XXX=, [email protected]) 

因爲你只關心第二,第四和護理第六場比賽,只收集那些。

因此該解決方案會是什麼樣子,

scala> extractionPattern.findAllIn("""/horses/[email protected]""") 
         .matchData.map(_.subgroups) 
         .flatMap(matches => Seq(matches(1), matches(3), matches(4))).toList 
res16: List[String] = List(horses, c132, ?XXX=) 

當您輸入不匹配正則表達式,你在這裏得到空結果

scala> extractionPattern.findAllIn("""/horses/c132""") 
         .matchData.map(_.subgroups) 
         .flatMap(matches => Seq(matches(1), matches(3), matches(4))).toList 
res17: List[String] = List() 

工作正則表達式 - https://regex101.com/r/HuGRls/1/

0
votes
answers
42 views
+10

訪問私有變量在斯卡拉測試沒有鑄造

0

我需要你的幫助,我有這個斯卡拉問題。訪問私有變量在斯卡拉測試沒有鑄造

我有一個類的層次結構:車輛只有每個車輛的共同變量,然後是3個子類:Car,Truck和MotorCycle,每個人都有自己的特定變量。 我使用模式匹配在輔助對象的方法來做這取決於車輛的類型的一些變換:

object Transformation { 
    def someTransformation(vehicle:Vehicle):Vehicle = { 
     vehicle match { 
      case Car(<<<vars>>>) => Car(<<< transformed vars>>>) 
      case Truck(<<<vars>>>) => Truck(<<< transformed vars>>>) 
      case MotorCycle(<<<vars>>>) => MotorCycle(<<< transformed vars>>>) 
     } 
    } 
} 

我的問題是,當我必須測試它,因爲我返回一個車輛(可以說一個混合),我必須在每次出現時都施放以便獲得所涉及的車輛的私人汽車。 我想離開這段代碼的樣子,並且在測試過程中訪問私有成員而不投射,知道我作爲參數收到的車輛與我返回的車輛類型相同。 這可以通過泛型來解決嗎?如何?

謝謝,我希望它是可以理解的。

+0

我猜你真的不意味着該類的'private'成員,繼承特定的公正? – Kraylog

+0

恰恰是尼姆羅德阿爾戈夫 –

沙发
0
1

我認爲你想要做的是對函數someTransformation的返回類型進行限制。你想someTransformation只返回它被調用的車輛的類型。

這裏是你如何通過上下文範圍做到這一點:

trait Vehicle 
case class Car(a: Int) extends Vehicle 
case class Truck(b: Int) with Vehicle 
case class MotorCycle(c: Int) with Vehicle 

object Transformation { 
    trait Transformer[V <: Vehicle] { 
    def transform(v: V): V 
    } 

    implicit val carTransformer = new Transformer[Car] { 
    override def transform(c: Car): Car = Car(c.a + 1) 
    } 

    implicit val truckTransformer = new Transformer[Truck] { 
    override def transform(t: Truck): Truck = Truck(t.b + 10) 
    } 

    implicit val motorCycleTransformer = new Transformer[MotorCycle] { 
    override def transform(m: MotorCycle): MotorCycle = MotorCycle(m.c + 100) 
    } 

    def someTransformation[V <: Vehicle : Transformer](v: V): V = { 
    implicitly[Transformer[V]].transform(v) 
    } 
} 

Transformation.someTransformation(Car(1)) // results in Car(2) 
Transformation.someTransformation(Truck(1)) // results in Truck(11) 
Transformation.someTransformation(MotorCycle(1)) // results in MotorCycle(101) 
0
votes
answers
31 views
+10

函數來處理多個現有獨立的數據定義

2

我有多個數據定義,作爲一個簡單的例子:函數來處理多個現有獨立的數據定義

data Fruit = Apple String Bool 
      | Cherry String String 
      | Grape String 

data Vegetable = Carrot String 
       | Onion Bool String 
       | Tomato String String 

現在我想有應進行兩種類型的函數,我想是這樣的:

f :: a -> String 
f (Carrot s) = s 
f (Apple s b) = s 
f (Onion b s) = s 
... 

但是這不起作用,因爲預期類型a不能與例如類型Carrot匹配。我想知道如何在模式匹配或其他技術的幫助下定義一個可以處理多個現有獨立數據定義的函數。

+2

您可以定義一個'?F::無論是果蔬 - > String',也可以定義一個類型類(和定義兩個'f's)。 –

+0

@WillemVanOnsem謝謝你的提示。我是對的,'只有'只有兩種類型? –

+2

沒有一種類型,即「任何水果蔬菜」類型。所以你寫'f(Left(Apple s b))= ...','f(Right(Carrot c))= ...'。 –

沙发
0
6

做你正在嘗試做的方法是與同時涉及食品新的數據類型,所以,讓我們把它叫做食物,這將是:

data Food = Veg Vegetable | Fr Fruit deriving Show 

data Fruit = Apple String Bool 
      | Cherry String String 
      | Grape String deriving Show 

data Vegetable = Carrot String 
       | Onion Bool String 
       | Tomato String String deriving Show 


f :: Food -> String 
f (Veg v) = fVeg v 
f (Fr f) = fFruit f 

fVeg (Carrot s) = s 
fVeg (Onion b s) = s 
fVeg (Tomato s1 s2) = s1 ++ s2 

fFruit (Apple s b) = s 
... 
... 

    f $ Veg $ Onion True "friend" 
=> "friend" 
+0

非常感謝。非常乾淨的解決方案,無需更改現有類 –

+0

@ClaudioP沒問題!我一直很喜歡幫助,我希望你接受兩個答案中的一個:) –

板凳
0
5

有兩個選項。一個是Damian Lattenero說的,另一個選擇是使用typeclasses。

class Food a where 
    f :: a -> String 

instance Food Fruit where 
    f (Apple ...) = ... 
    f (Cherry ...) = ... 
    f ... 

instance Food Vegetable where 
    f (Carrot ...) = ... 
    f (Onion ...) = ... 
    f (Tomato ...) = ... 

問題是你不能有,例如,食物的列表,因爲水果和蔬菜是不同的類型。但是你可以在沒有問題的情況下使用f。

編輯:

另一種選擇,存在量化,以在列表中有兩種類型,但是隻將f應用到數據(也使用上面的代碼):

{-# LANGUAGE ExistentialQuantification #-} 

data F = forall a. (Food a) => F a 

instance Food F where 
    f (F x) = f x 

xs :: [F] 
xs = [F (Apple ...), F (Carrot ..), F (Tomato ...)] 

的一個例子,函數使用F:

mapF :: [F] -> [String] 
mapF xs = map f xs 
+2

請注意,typeclasses + existstentials通常會導致[已知的反模式](https://lukepalmer.wordpress.com/2010/01/24/haskell -antipattern-存在-類型類/) – chi

0
votes
answers
31 views
+10

在safeTail函數中的Haskell模式匹配

-3

我得到了一個使用模式匹配定義的Haskell函數,但我不是很明白爲什麼它看起來像它的樣子。在safeTail函數中的Haskell模式匹配

safeTail (x : xs) = xs 

我不是特別明白在(x:xs),這是什麼意思?

+0

如果是這樣的功能的完整定義,我會已命名爲'unsafeTail'或'dangerousTail',因爲這將在空列表中崩潰。 – chi

+0

我得到了空列表的catchall,但決定不把它放在這裏,因爲這裏的重點是我不明白(x:xs)的語法而不是函數。 – Wandy

沙发
0
1

那就是模式匹配。

函數safeTail的第一個參數是一些列表類型。如果參數是非空列表,則此模式匹配將成功並將x綁定到head元素,將xs綁定到列表的尾部。

如果您將空列表傳遞給safeTail,則模式匹配將失敗,並檢查其他模式(如果存在)。

板凳
0
2

考慮列表數據類型的類似定義。

data List a = Empty | Cons a (List a) -- (1) 

有兩個構造函數:一個用於創建一個空列表,另一個用於創建一個給定值和另一個列表的列表。

模式匹配通過將值與用於創建它的構造函數進行匹配來工作。

safeTail (Cons x xs) = xs -- (2) 

也就是說,如果safeTail被施加到使用Cons構造定義的值,則返回值是第二個參數Cons

在實際的代碼,這兩個類型構造ListEmpty數據構造被命名爲[]Cons構造被命名爲(:)

data [] a = [] | (:) a ([] a) 

其中的Haskell允許以特殊語法

data [a] = [] | a : [a] 

應用類型建築工[]的類型或類型變量被寫入可以通過包括[]內部的參數,和所述符號構造器(代替因爲它以:開頭)可以用作中綴運算符。

也就是說,可以編寫

safeTail ((:) x xs) = xs -- (3) 

safeTail (x : xs) = xs -- (4) 

與(2),(3),和(4)等效於上述(1)。

>>> safeTail ((:) 3 ((:) 2 ((:) 1 []))) 
[2,1] 
>>> safeTail (3:2:1:[]) 
[2,1] 
>>> safeTail [3,2,1] 
[2,1] 

爲了進一步簡化,Haskell中表示(x:[])[x](x:y:[])[x,y]作爲等

safeTail一個完整的定義也將一個空的list參數提供一個值:

safeTail [] = [] 

Maybe基於定義

safeTail :: [a] -> Maybe [a] 
safeTail [] = Nothing 
safeTail (x:xs) = Just xs 
+0

基於'Maybe'的定義實際上是一個'safeHead'而不是'safeTail' – 4castle

0
votes
answers
32 views
+10

F#模式匹配出錯了

3

我剛剛開始使用F#,所以這可能是一個微不足道的問題,但我無法理解爲什麼我的代碼中的模式匹配就像它一樣行事。代碼的F#模式匹配出錯了

快速解釋:
的FUNC calcNextMatch應該遞歸一個列表,如果2個元素是相等的它們應該被加在一起。 最後,func應該返回一個數字,即添加與列表中下一位數字匹配的所有數字。
f.ex. [1; 3; 2; 2; 5]應返回4

代碼:

let rec printList l = 
    match l with 
    | head :: tail -> printf "%d " head; printList tail 
    | [] -> printfn "" 

let rec calcNextMatch list = 
    printList list 
    match list with 
    | [] -> 0 
    | _ :: tail ->    
     printList tail 
     let h = Seq.head list 
     let t = Seq.tryHead tail 
     printfn "h: %i" h 
     printfn "t: %O" t 
     match t with 
     | Some h -> 
      printfn "TAIL t: %i is equal to HEAD h: %i" t.Value h 
      printfn "Calculation is: %i" (t.Value + h) 
      (t.Value + h) + calcNextMatch tail 
     | _ -> calcNextMatch tail 

let sequence = [ 1;3;2;2;5 ] 
let run = calcNextMatch sequence 

當運行該代碼的問題是,模式匹配 如我期望它不起作用。從運行腳本f.ex f.ex打印輸出。

h: 1 
t: Some(3) 
TAIL t: 3 is equal to HEAD h: 3 

這意味着F#已在的情況下匹配

match t with 
     | Some h -> 

其中t =一些(3)和h = 1 其轉換爲

match 3 with 
     | Some 1 -> 

和我不理解。 匹配狀態之前打印噸和h的給和但在值的模式匹配的?值已更改爲
這是如何實現?

+0

'某些h'聲明瞭一個新的變量'h',與現有變量的值不匹配。 – Mankarse

沙发
0
3

您只能對常量字面值進行匹配模式匹配,否則該值會像有新的綁定一樣受限制。

在這種情況下,你做正常的是添加when條件:

match t with 
    | Some x when x = h -> 

另請注意,您可以使用模式匹配進一步簡化代碼,比如這裏:

| _ :: tail ->    
    printList tail 
    let h = Seq.head list 

你可以這樣寫:

| h :: tail ->    
    printList tail 

同樣所有這部分:

| _ :: tail ->    
    printList tail 
    let h = Seq.head list 
    let t = Seq.tryHead tail 
    printfn "h: %i" h 
    printfn "t: %O" t 
    match t with 
    | Some h -> 
     printfn "TAIL t: %i is equal to HEAD h: %i" t.Value h 
     printfn "Calculation is: %i" (t.Value + h) 
     (t.Value + h) + calcNextMatch tail 

變爲:

| h :: tail ->    
    printList tail 
    //printfn "h: %i" h 
    //printfn "t: %O" t 
    match tail with 
    | t::_ when t = h -> 
     printfn "TAIL t: %i is equal to HEAD h: %i" t h 
     printfn "Calculation is: %i" (t + h) 
     (t + h) + calcNextMatch tail 

而且你可以在統一一個所有比賽,那麼你的整個功能變爲:

let rec calcNextMatch list = 
    printList list 
    match list with 
    | [] -> 0 
    | h::x::tail when x = h -> x + h + calcNextMatch (x::tail) 
    | _::tail -> calcNextMatch tail 

最後,當你與調試完成後,你可以刪除打印並且由於您的功能的最後一個參數是您匹配的那個,您可以使用關鍵字function,也可以使用as模式來避免重新構建列表:

let rec calcNextMatch = function 
    | [] -> 0 
    | h::((x::_) as tail) when x = h -> x + h + calcNextMatch tail 
    | _::tail -> calcNextMatch tail 
+1

感謝您的幫助和全面的解釋。我現在明白了。 我還假設這是我不知道F#做的事情。 現在我的算法做它應該做的:-D – ThBlitz