If I create the following multi-line string literal:
let lit = "A -> B
C -> D
E -> F";
It prints out like this:
A -> B
C -> D
E -> F
No surprise. However, if I try this:
let lit = "A -> B\
C -> D\
E -> F";
I get:
A -> BC -> DE -> F
What I'm trying to get is this:
A -> B
C -> D
E -> F
But this is the best thing I've come up with:
let lit = "A -> B\n\
C -> D\n\
E -> F";
Or maybe this:
let lit = vec!["A -> B", "C -> D", "E -> F"].connect("\n");
Both of those feel a little clunky, though not terrible. Just wondering if there's any cleaner way?
Indoc is a procedural macro that does what you want. It stands for "indented document." It provides a macro called indoc!() that takes a multiline string literal and un-indents it so the leftmost non-space character is in the first column.
let lit = indoc! {"
A -> B
C -> D
E -> F"
};
The result is "A -> B\nC -> D\nE -> F" as you asked for.
Whitespace is preserved relative to the leftmost non-space character in the document, so the following preserves 2 spaces before "C":
let lit = indoc! {"
A -> B
C -> D
E -> F"
};
The result is "A -> B\n C -> D\nE -> F".
I see three other possible solutions:
1) Get rid of the spaces:
let lit = "A -> B
C -> D
E -> F";
This way, you lose the neat display in your code. You could get that back like this:
2) Get rid of the spaces, shift everything down a line, and escape the return.
let lit = "\
A -> B
C -> D
E -> F";
I would explain what that "\" is doing in a comment, though, because it isn't obvious otherwise.
3) Combine these two solutions:
let lit =
"A -> B
C -> D
E -> F";
You can test this at Ideone.
Mostly as an exercise, I mimicked Python's join syntax with the following:
trait CanJoin {
fn join(&self, in_strings: Vec<&str>) -> String;
}
impl CanJoin for str {
fn join(&self, in_strings: Vec<&str>) -> String {
in_strings.connect(self)
}
}
fn main() {
let vector = vec!["A -> B", "B -> C", "C -> D"];
let joined = "\n".join(vector);
}
Or as a macro:
macro_rules! join_lines {
($($x:tt)*) => {
{
vec![$($x)*].connect("\n")
}
}
}
let joined = join_lines!("A -> B", "B -> C", "C -> D");
Related
With a case _ of syntax like this:
fun a b c =
case (a, b, c) of
(Just True, Just _, _) -> foo
(Just True, _, Just _) -> foo
_ -> bar
Can I merge the first two conditions and avoid repeating foo?
Alternatively, is there any other (cleaner) way to express that I want to run foo if and only if a is Just True and either b or c are not Nothing?
You can do something like this:
fun a b c = case (a, b <|> c) of
(Just True, Just _) -> foo
_ -> bar
Of course, that's just hiding the extra match in (<|>), but you gotta pay the piper some time.
If b and c do not have the same type, you can cause them to with the ill-named void.
Let me complement the other answers with a "boring" alternative:
fun a b c = let
foo' = foo
in case (a, b, c) of
(Just True, Just _, _) -> foo'
(Just True, _, Just _) -> foo'
_ -> bar
This might or might not answer the intended question, depending on the actual goal.
If the goal was to avoid writing two patterns in the case, this of course fails to meet the goal.
If instead the goal was to avoid repeating foo, which could be a very long expression (e.g., a long do block in some monad), this meets the goal by giving a short name to the long expression.
Don't know if this looks cleaner but you could use the good old pal if too:
fun a b c =
if a == Just True && (isJust b || isJust c)
then foo
else bar
or use guards
fun a b c =
case a of
Just True | isJust b || isJust c -> foo
_ -> bar
without case:
fun (Just True) b c | isJust b || isJust c = foo
fun _ _ _ = bar
all is using isJust and as Daniel pointed out those too will give the piper it's due (pattern match).
After the Data Analysis & getting the Required Result I'm appending that result to a List
Now I Need to Retrieve Or Separate the Result (Search For Pattern & Obtain It)
Code:
data = []
data.append('\n'.join([' -> '.join(e) for e in paths]))
List Contais This data:
CH_Trans -> St_1 -> WDL
TRANSFER_Trn -> St_1
Access_Ltd -> MPL_Limited
IPIPI -> TLC_Pvt_Ltd
234er -> Three_Star_Services -> Asian_Pharmas -> PPP_Channel
Sonata_Ltd -> Three_Star_Services
Arc_Estates -> Russian_Hosp
A -> B -> C -> D -> E -> F
G -> H
ZN_INTBNKOUT_SET -> -2008_1 -> X
ZZ_1_ -> AA_2 -> AA_3 -> ZZ_1_
XYZ- -> ABC -> XYZ-
SSS -> BBB -> SSS
Rock_8CC -> Russ -> By_sus -> Rock_8CC
Note : Display or Retrieve Pattern Which has more than two symbol of type[->]
( Txt -> txt -> txt )
I'm Trying to get it Done by Regex
for i in data:
regex = ("\w+\s->\s\w+\s->\s\w+")
match = re.findall(regex, i,re.MULTILINE)
print(match)
Regex Expression I Tried But Unable to get Requried Result
#\w+\s->\s\w+\s->\s\w+
#\w+\s[-][>]\s\w+\s[-][>]\s\w+
#\w+\s[-][>]\s\w+\s[-][>]\s\w+\s[-][>]\s\w+
Result I Got
['CH_Trans-> St_1-> WDL', '234er -> Three_Star_Services -> Asian_Pharmas',
'A -> B -> C', 'D -> E -> F', 'ZZ_1_ -> AA_2 -> AA_3',
'SSS -> BBB -> SSS', 'Rock_8CC -> Russ -> By_sus']
Requried Result What I want to Obtain is
----Pattern I------
CH_Trans -> St_1 -> WDL
234er -> Three_Star_Services -> Asian_Pharmas -> PPP_Channel
A -> B -> C -> D -> E -> F
ZN_INTBNKOUT_SET -> -2008_1 -> X
# Pattern II Consists of Patterns which are same i.e[ Fist_ele & Last_Ele Is Same]
----Pattern II------
ZZ_1_ -> AA_2 -> AA_3 -> ZZ_1_
XYZ- -> ABC -> XYZ-
SSS -> BBB -> SSS
Rock_8CC -> Russ -> By_sus -> Rock_8CC
Would you please try the following as a starting point:
regex = r'^\S+(?:\s->\s\S+){2,}$'
for i in data:
m = re.match(regex, i)
if (m):
print(m.group())
Results (Pattern I + Pattern II):
CH_Trans -> St_1 -> WDL
234er -> Three_Star_Services -> Asian_Pharmas -> PPP_Channel
A -> B -> C -> D -> E -> F
ZN_INTBNKOUT_SET -> -2008_1 -> X
ZZ_1_ -> AA_2 -> AA_3 -> ZZ_1_
XYZ- -> ABC -> XYZ-
SSS -> BBB -> SSS
Rock_8CC -> Russ -> By_sus -> Rock_8CC
Explanation of the regex ^\S+(?:\s->\s\S+){2,}$:
^\S+ start with non-blank string
(?: ... ) grouping
\s->\s\S+ a blank followed by "->" followed by a blank and non-blank string
{2,} repeats the previous pattern (or group) two or more times
$ end of the string
As of pattern II please say:
regex = r'^(\S+)(?:\s->\s\S+){1,}\s->\s\1$'
for i in data:
m = re.match(regex, i)
if (m):
print(m.group())
Results:
ZZ_1_ -> AA_2 -> AA_3 -> ZZ_1_
XYZ- -> ABC -> XYZ-
SSS -> BBB -> SSS
Rock_8CC -> Russ -> By_sus -> Rock_8CC
Explanation of regex r'^(\S+)(?:\s->\s\S+){1,}\s->\s\1$':
- ^(\S+) captures the 1st element and assigns \1 to it
- (?: ... ) grouping
- \s->\s\S+ a blank followed by "->" followed by a blank and non-blank string
- {1,} repeats the previous pattern (or group) one or more times
- \s->\s\1 a blank followed by "->" followed by a blank and the 1st element \1
- $ end of the string
In order to obtain the result of pattern I, we may need to subtract the list of pattern II from the 1st results.
If we could say:
regex = r'^(\S+)(?:\s->\s\S+){2,}(?<!\1)$'
it will exclude the string whose last element differs from the 1st element then we could obtain the result of pattern I directry but the regex causes the error saying "group references in lookbehind assertions" so far.
Real beginners question here. How do I represent a problem with multiple hypotheses in Lean? For example:
Given
A
A→B
A→C
B→D
C→D
Prove the proposition D.
(Problem taken from The Incredible Proof Machine, Session 2 problem 3. I was actually reading Logic and Proof, Chapter 4, Propositional Logic in Lean but there are less exercises available there)
Obviously this is completely trivial to prove by applying modus ponens twice, my question is how do I represent the problem in the first place?! Here's my proof:
variables A B C D : Prop
example : (( A )
/\ ( A->B )
/\ ( A->C )
/\ ( B->D )
/\ ( C->D ))
-> D :=
assume h,
have given1: A, from and.left h,
have given2: A -> B, from and.left (and.right h),
have given3: A -> C, from and.left (and.right (and.right h)),
have given4: B -> D, from and.left (and.right (and.right (and.right h))),
have given5: C -> D, from and.right (and.right (and.right (and.right h))),
show D, from given4 (given2 given1)
Try it!
I think I've made far too much a meal of packaging up the problem then unpacking it, could someone show me a better way of representing this problem please?
I think it is a lot clearer by not using And in the hypotheses instead using ->. here are 2 equivalent proofs, I prefer the first
def s2p3 {A B C D : Prop} (ha : A)
(hab : A -> B) (hac : A -> C)
(hbd : B -> D) (hcd : C -> D) : D
:= show D, from (hbd (hab ha))
The second is the same as the first except using example,
I believe you have to specify the names of the parameters using assume
rather than inside the declaration
example : A -> (A -> B) -> (A -> C) -> (B -> D) -> (C -> D) -> D :=
assume ha : A,
assume hab : A -> B,
assume hac, -- You can actually just leave the types off the above 2
assume hbd,
assume hcd,
show D, from (hbd (hab ha))
if you want to use the def syntax but the problem is e.g. specified using example syntax
example : A -> (A -> B) -> (A -> C)
-> (B -> D) -> (C -> D) -> D := s2p3
Also, when using and in your proof, in the unpacking stage
You unpack given3, and given 5 but never use them in your "show" proof.
So you don't need to unpack them e.g.
example : (( A )
/\ ( A->B )
/\ ( A->C )
/\ ( B->D )
/\ ( C->D ))
-> D :=
assume h,
have given1: A, from and.left h,
have given2: A -> B, from and.left (and.right h),
have given4: B -> D, from and.left (and.right (and.right (and.right h))),
show D, from given4 (given2 given1)
Background: I'm working with wxHaskell's fileOpenDialog, which takes 6 non-obvious parameters (curried). My code is currently:
maybePath <- fileOpenDialog w useLastSelectedDir canSelectReadOnly
frameName possibleFiles initialDir defaultFilename
with a let statement above that to define all my parameters. What I would love to do though, is save my parameters somewhere. I somewhat understand why Haskell would't support something like say:
myParams = ( ... ) -- tuple of params
maybePath <- fileOpenDialog myParams
However, is there something close to this in the spirit of not repeating myself?
It seems like you would naturally like the input to this function to be a record of parameters:
{-# LANGUAGE RecordWildCards #-}
-- Defined by your library
foo :: String -> Int -> IO ()
foo = ...
data Opts = Opts { optString :: String, optInt :: Int }
bar :: Opts -> IO ()
bar Opts{..} = foo optString optInt
Now, you can use any of the following equivalent syntaxes (some use RecordWildCards):
main = do
let optString = <...>
optInt = <...>
bar Opts{..}
main = do
let x = <...>
y = <...>
myParams = Opts x y
bar myParams
main = do
bar $ Opts
{ optString = <...>
, optInt = <...>
}
main = do
let optString = <...>
optInt = <...>
myParams = Opts{..}
bar myParams
There is also the (less clean) possibility of writing an uncurry variant (see here) having more arguments:
uncurry6 :: (a -> b -> c -> d -> e -> f -> g) -> ((a,b,c,d,e,f) -> g)
uncurry6 fun (a,b,c,d,e,f) = fun a b c d e f
Having that, uncurry6 fileOpenDialog will make fileOpenDialog accept a 6-tuple.
I have a list as let a = ["q0,x";"q1,y"]; which is of type string list.
I want to make it as [("q0","x");("q1","y")]; which is a list of (string * string) tuples.
How do I do that??
You can use module Str and the function split :
let split =
List.map (fun str ->
match Str.split (Str.regexp ",") str with
| a :: b :: _ -> a, b
| _ -> assert false (* should not happen *))