Are the brackets fully matched? You must write a program or function that takes a string of brackets and outputs whether or not that string is fully matched. Your program should print a truthy or falsy value, and IO can be in any reasonable format.
Rules and definitions:

For the purpose of this challenge, a &quot;bracket&quot; is any of these characters: ()[]{}&lt;&gt;.

A pair of brackets is considered &quot;matched&quot; if the opening and closing brackets are in the right order and have no characters inside of them, such as
()
[]{}

Or if every subelement inside of it is also matched.
[()()()()]
{&lt;[]&gt;}
(()())

Subelements can also be nested several layers deep.
[(){&lt;&gt;&lt;&gt;[()]}&lt;&gt;()]
&lt;[{((()))}]&gt;


A string is considered &quot;Fully matched&quot; if and only if:

Every single character is a bracket,

Each pair of brackets has the correct opening and closing bracket and in the right order, and

Each bracket is matched.



You may assume the input will only contain printable ASCII.


Test IO
Here are some inputs that should return a truthy value:
()
[](){}&lt;&gt;
(((())))
({[&lt;&gt;]})
[{()&lt;&gt;()}[]]
[([]{})&lt;{[()&lt;()&gt;]}()&gt;{}]

And here are some outputs that should return a falsy value:
(               Has no closing ')'
}{              Wrong order
(&lt;)&gt;            Each pair contains only half of a matched element
(()()foobar)    Contains invalid characters
[({}&lt;&gt;)&gt;        The last bracket should be ']' instead of '&gt;'
(((()))         Has 4 opening brackets, but only 3 closing brackets.

As usual, this is code-golf, so standard loopholes apply, and shortest answer in bytes wins.
Brain-Flak, 1101, 1085, 981 bytes

{(&lt;(({}))((((()()()()()){}){}){})({}[{}]&lt;(())&gt;){((&lt;{}{}&gt;))}{}&gt;{({}&lt;&gt;)(&lt;&gt;)}{}&lt;(({
}))((((()()()()()){}){}){}())({}[{}]&lt;(())&gt;){((&lt;{}{}&gt;))}{}&gt;{({}&lt;&gt;)({}[{}](&lt;()&gt;)){
{}{}(&lt;(())&gt;)}{}{&lt;&gt;{{}}&lt;&gt;{{}}((&lt;()&gt;))}{}(&lt;&gt;)}{}&lt;(({}))(((((()()()()()){}){})){}{}
)({}[{}]&lt;(())&gt;){((&lt;{}{}&gt;))}{}&gt;{&lt;({}()&lt;&gt;)&gt;()(&lt;&gt;)}{}&lt;(({}))(((((()()()()()){}){})(
)){}{})({}[{}]&lt;(())&gt;){((&lt;{}{}&gt;))}{}&gt;{&lt;({}()&lt;&gt;)&gt;()({}[{}](&lt;()&gt;)){{}{}(&lt;(())&gt;)}{}{
&lt;&gt;{{}}&lt;&gt;{{}}((&lt;()&gt;))}{}(&lt;&gt;)}{}&lt;(({}))((((()()()){}){}()){({}[()])}{})({}[{}]&lt;(()
)&gt;){((&lt;{}{}&gt;))}{}&gt;{&lt;({}()()&lt;&gt;)&gt;()(&lt;&gt;)}{}&lt;(({}))((((((()()()()()){})){}{}())){}{}
)({}[{}]&lt;(())&gt;){((&lt;{}{}&gt;))}{}&gt;{&lt;({}()()&lt;&gt;)&gt;()({}[{}](&lt;()&gt;)){{}{}(&lt;(())&gt;)}{}{&lt;&gt;{{
}}&lt;&gt;{{}}((&lt;()&gt;))}{}(&lt;&gt;)}{}&lt;(({}))((((((()()()()()){}){}){}())){}{})({}[{}]&lt;(())&gt;
){((&lt;{}{}&gt;))}{}&gt;{&lt;({}()()()&lt;&gt;)&gt;()(&lt;&gt;)}{}&lt;(({}))((((((()()()()()){}){}){}())()){}
{})({}[{}]&lt;(())&gt;){((&lt;{}{}&gt;))}{}&gt;{&lt;({}()()()&lt;&gt;)&gt;()({}[{}](&lt;()&gt;)){{}{}(&lt;(())&gt;)}{}{
&lt;&gt;{{}}&lt;&gt;{{}}((&lt;()&gt;))}{}(&lt;&gt;)}{}&lt;{}&gt;[()]){&lt;&gt;{{}}(&lt;()&gt;)&lt;&gt;{{}}(&lt;()&gt;)}{}}&lt;&gt;([]&lt;&gt;)({}&lt;
(())&gt;){((&lt;{}{}&gt;))}{}


Try it online!

This is 980 bytes of source code, and +1 for the -a flag allowing ASCII input (but decimal output)

This is an answer I've been wanting to write for a very very long time. At least 6 months. I waited to post this because I knew that answering this challenge would be extra hard in brain-flak. But it's worth it for one very important reason: The source code itself is a truthy input, which is the entire point of this language itself.

And as I wrote about here, this question was what inspired me to write brain-flak. 


  Shortly after I wrote Are the brackets fully matched?, it made me wonder how much information you can store with only matched brackets. One thing that stood out to me, was that even though you only have 4 "atoms" of sorts:

(){}[]&lt;&gt;

  
  you really have 8 units of information to convey, since each of these bracket types can be empty, or have other brackets in between, which are fundamentally different pieces of information. So, I decided to write a language that only allowed for matched brackets, and where empty brackets convey something different than brackets with other brackets inside of them.


This answer took roughly two hours to write. I'll admit it's pretty poorly golfed, mostly because a lot of the code is repeated for each bracket type. But I'm mostly amazed that I was able to write an answer at all, especially given that Brain-Flak is


  A minimalist esolang designed to be painful to use


I'm going to attempt to golf it down later, but I wanted to get this out there anyway.

I have a detailed explanation, but it's about 6 thousand characters long, so I think it would not be wise to paste the entire thing into this answer. You can read through it here if you want. I'll add a shorter explanation here.

The basic idea, is that we repeat the following steps for every character on the stack:


We check each character to see if it matches any bracket. If it is an opening bracket, we push a number onto the other stack according to the following mapping:

( = 1
&lt; = 2
[ = 3
{ = 4

Then we check to see if it matches any closing bracket. If it does, we push the equivalent number onto the alternate stack, just like for opening brackets. Then, we check if the top two numbers are equal. If they are, the both get popped and the program continues as normal. If they are not, we clear both stacks (to stop the looping) and push a one onto the alternate stack. This is essentially a "break" statement.
After checking the 8 bracket types, we push the value of this run through the loop. Since we zero out most of it, the only snippets that have any value are the conditionals when we compare against brackets. So if any bracket is matched, the whole loop has a value of 1. If none of them did, the whole loop has a value of 0. In this case, we will clear both stacks and push a 0 onto the alternate stack. Again, this is like a "break" statement.


After this main loop is running, the rest is fairly simple. We are on the (empty) main stack, and the alternate stack is empty (if the brackets were matched) or non-empty if they were not. So we run this:

#Toggle to the alternate stack
&lt;&gt;

#Push this stack-height onto main-stack
([]&lt;&gt;)

#Logical not
({}&lt;(())&gt;){((&lt;{}{}&gt;))}{}


This will push a 0 or a 1 onto the main-stack, and when the program ends it is implicitly printed.




Thanks to @WheatWizard for coming up with a good stack-clean "equals" and "logical not" snippet, and for regularly updating the github wiki with useful examples.
Thanks to @ASCII-only for writing an online integer metagolfer which helped immensely in writing this program




revisions


Removed some push pop redundancy
Changed my zero counter logic